drm_WARN_ON(&i915->drm, sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
 }
 
+/*
+ * vGPU type name is defined as GVTg_Vx_y which contains the physical GPU
+ * generation type (e.g V4 as BDW server, V5 as SKL server).
+ *
+ * Depening on the physical SKU resource, we might see vGPU types like
+ * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create different types of
+ * vGPU on same physical GPU depending on available resource. Each vGPU
+ * type will have a different number of avail_instance to indicate how
+ * many vGPU instance can be created for this type.
+ */
 #define VGPU_MAX_WEIGHT 16
 #define VGPU_WEIGHT(vgpu_num)  \
        (VGPU_MAX_WEIGHT / (vgpu_num))
 
-static const struct {
-       unsigned int low_mm;
-       unsigned int high_mm;
-       unsigned int fence;
-
-       /* A vGPU with a weight of 8 will get twice as much GPU as a vGPU
-        * with a weight of 4 on a contended host, different vGPU type has
-        * different weight set. Legal weights range from 1 to 16.
-        */
-       unsigned int weight;
-       enum intel_vgpu_edid edid;
-       const char *name;
-} vgpu_types[] = {
-/* Fixed vGPU type table */
+static const struct intel_vgpu_config intel_vgpu_configs[] = {
        { MB_TO_BYTES(64), MB_TO_BYTES(384), 4, VGPU_WEIGHT(8), GVT_EDID_1024_768, "8" },
        { MB_TO_BYTES(128), MB_TO_BYTES(512), 4, VGPU_WEIGHT(4), GVT_EDID_1920_1200, "4" },
        { MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, VGPU_WEIGHT(2), GVT_EDID_1920_1200, "2" },
  */
 int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
 {
-       unsigned int num_types;
-       unsigned int i, low_avail, high_avail;
-       unsigned int min_low;
-
-       /* vGPU type name is defined as GVTg_Vx_y which contains
-        * physical GPU generation type (e.g V4 as BDW server, V5 as
-        * SKL server).
-        *
-        * Depend on physical SKU resource, might see vGPU types like
-        * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create
-        * different types of vGPU on same physical GPU depending on
-        * available resource. Each vGPU type will have "avail_instance"
-        * to indicate how many vGPU instance can be created for this
-        * type.
-        *
-        */
-       low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
-       high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
-       num_types = ARRAY_SIZE(vgpu_types);
+       unsigned int low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
+       unsigned int high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
+       unsigned int num_types = ARRAY_SIZE(intel_vgpu_configs);
+       unsigned int i;
 
        gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type),
                             GFP_KERNEL);
        if (!gvt->types)
                return -ENOMEM;
 
-       min_low = MB_TO_BYTES(32);
        for (i = 0; i < num_types; ++i) {
-               if (low_avail / vgpu_types[i].low_mm == 0)
-                       break;
-
-               gvt->types[i].low_gm_size = vgpu_types[i].low_mm;
-               gvt->types[i].high_gm_size = vgpu_types[i].high_mm;
-               gvt->types[i].fence = vgpu_types[i].fence;
+               const struct intel_vgpu_config *conf = &intel_vgpu_configs[i];
 
-               if (vgpu_types[i].weight < 1 ||
-                                       vgpu_types[i].weight > VGPU_MAX_WEIGHT)
+               if (low_avail / conf->low_mm == 0)
+                       break;
+               if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT)
                        goto out_free_types;
 
-               gvt->types[i].weight = vgpu_types[i].weight;
-               gvt->types[i].resolution = vgpu_types[i].edid;
-               gvt->types[i].avail_instance = min(low_avail / vgpu_types[i].low_mm,
-                                                  high_avail / vgpu_types[i].high_mm);
-
-               if (GRAPHICS_VER(gvt->gt->i915) == 8)
-                       sprintf(gvt->types[i].name, "GVTg_V4_%s",
-                               vgpu_types[i].name);
-               else if (GRAPHICS_VER(gvt->gt->i915) == 9)
-                       sprintf(gvt->types[i].name, "GVTg_V5_%s",
-                               vgpu_types[i].name);
+               sprintf(gvt->types[i].name, "GVTg_V%u_%s",
+                       GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
+               gvt->types[i].conf = conf;
+               gvt->types[i].avail_instance = min(low_avail / conf->low_mm,
+                                                  high_avail / conf->high_mm);
 
                gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n",
-                            i, gvt->types[i].name,
-                            gvt->types[i].avail_instance,
-                            gvt->types[i].low_gm_size,
-                            gvt->types[i].high_gm_size, gvt->types[i].fence,
-                            gvt->types[i].weight,
-                            vgpu_edid_str(gvt->types[i].resolution));
+                            i, gvt->types[i].name, gvt->types[i].avail_instance,
+                            conf->low_mm, conf->high_mm, conf->fence,
+                            conf->weight, vgpu_edid_str(conf->edid));
        }
 
        gvt->num_types = i;
                gvt->fence.vgpu_allocated_fence_num;
 
        for (i = 0; i < gvt->num_types; i++) {
-               low_gm_min = low_gm_avail / gvt->types[i].low_gm_size;
-               high_gm_min = high_gm_avail / gvt->types[i].high_gm_size;
-               fence_min = fence_avail / gvt->types[i].fence;
+               low_gm_min = low_gm_avail / gvt->types[i].conf->low_mm;
+               high_gm_min = high_gm_avail / gvt->types[i].conf->high_mm;
+               fence_min = fence_avail / gvt->types[i].conf->fence;
                gvt->types[i].avail_instance = min(min(low_gm_min, high_gm_min),
                                                   fence_min);
 
                gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n",
                       i, gvt->types[i].name,
-                      gvt->types[i].avail_instance, gvt->types[i].low_gm_size,
-                      gvt->types[i].high_gm_size, gvt->types[i].fence);
+                      gvt->types[i].avail_instance, gvt->types[i].conf->low_mm,
+                      gvt->types[i].conf->high_mm, gvt->types[i].conf->fence);
        }
 }
 
        vfree(vgpu);
 }
 
-static int __intel_gvt_create_vgpu(struct intel_vgpu *vgpu,
-                                  struct intel_vgpu_creation_params *param)
+int intel_gvt_create_vgpu(struct intel_vgpu *vgpu,
+               const struct intel_vgpu_config *conf)
 {
        struct intel_gvt *gvt = vgpu->gvt;
        struct drm_i915_private *dev_priv = gvt->gt->i915;
        int ret;
 
-       gvt_dbg_core("low %llu MB high %llu MB fence %llu\n",
-                       param->low_gm_sz, param->high_gm_sz,
-                       param->fence_sz);
+       gvt_dbg_core("low %u MB high %u MB fence %u\n",
+                       BYTES_TO_MB(conf->low_mm), BYTES_TO_MB(conf->high_mm),
+                       conf->fence);
 
+       mutex_lock(&gvt->lock);
        ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU,
                GFP_KERNEL);
        if (ret < 0)
-               return ret;
+               goto out_unlock;;
 
        vgpu->id = ret;
-       vgpu->sched_ctl.weight = param->weight;
+       vgpu->sched_ctl.weight = conf->weight;
        mutex_init(&vgpu->vgpu_lock);
        mutex_init(&vgpu->dmabuf_lock);
        INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
        INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL);
        idr_init_base(&vgpu->object_idr, 1);
-       intel_vgpu_init_cfg_space(vgpu, param->primary);
+       intel_vgpu_init_cfg_space(vgpu, 1);
        vgpu->d3_entered = false;
 
        ret = intel_vgpu_init_mmio(vgpu);
        if (ret)
                goto out_clean_idr;
 
-       ret = intel_vgpu_alloc_resource(vgpu, param);
+       ret = intel_vgpu_alloc_resource(vgpu, conf);
        if (ret)
                goto out_clean_vgpu_mmio;
 
        if (ret)
                goto out_clean_gtt;
 
-       ret = intel_vgpu_init_display(vgpu, param->resolution);
+       ret = intel_vgpu_init_display(vgpu, conf->edid);
        if (ret)
                goto out_clean_opregion;
 
        if (ret)
                goto out_clean_sched_policy;
 
+       intel_gvt_update_vgpu_types(gvt);
+       intel_gvt_update_reg_whitelist(vgpu);
+       mutex_unlock(&gvt->lock);
        return 0;
 
 out_clean_sched_policy:
        intel_vgpu_clean_mmio(vgpu);
 out_clean_idr:
        idr_remove(&gvt->vgpu_idr, vgpu->id);
-       return ret;
-}
-
-/**
- * intel_gvt_create_vgpu - create a virtual GPU
- * @gvt: GVT device
- * @type: type of the vGPU to create
- *
- * This function is called when user wants to create a virtual GPU.
- *
- * Returns:
- * pointer to intel_vgpu, error pointer if failed.
- */
-int intel_gvt_create_vgpu(struct intel_vgpu *vgpu, struct intel_vgpu_type *type)
-{
-       struct intel_gvt *gvt = vgpu->gvt;
-       struct intel_vgpu_creation_params param;
-       int ret;
-
-       param.primary = 1;
-       param.low_gm_sz = type->low_gm_size;
-       param.high_gm_sz = type->high_gm_size;
-       param.fence_sz = type->fence;
-       param.weight = type->weight;
-       param.resolution = type->resolution;
-
-       /* XXX current param based on MB */
-       param.low_gm_sz = BYTES_TO_MB(param.low_gm_sz);
-       param.high_gm_sz = BYTES_TO_MB(param.high_gm_sz);
-
-       mutex_lock(&gvt->lock);
-       ret = __intel_gvt_create_vgpu(vgpu, ¶m);
-       if (!ret) {
-               /* calculate left instance change for types */
-               intel_gvt_update_vgpu_types(gvt);
-               intel_gvt_update_reg_whitelist(vgpu);
-       }
+out_unlock:
        mutex_unlock(&gvt->lock);
-
        return ret;
 }