.emulate_mmio_write = intel_vgpu_emulate_mmio_write,
        .vgpu_create = intel_gvt_create_vgpu,
        .vgpu_destroy = intel_gvt_destroy_vgpu,
+       .vgpu_release = intel_gvt_release_vgpu,
        .vgpu_reset = intel_gvt_reset_vgpu,
        .vgpu_activate = intel_gvt_activate_vgpu,
        .vgpu_deactivate = intel_gvt_deactivate_vgpu,
 
 struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
                                         struct intel_vgpu_type *type);
 void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu);
+void intel_gvt_release_vgpu(struct intel_vgpu *vgpu);
 void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
                                 unsigned int engine_mask);
 void intel_gvt_reset_vgpu(struct intel_vgpu *vgpu);
                                unsigned int);
        struct intel_vgpu *(*vgpu_create)(struct intel_gvt *,
                                struct intel_vgpu_type *);
-       void (*vgpu_destroy)(struct intel_vgpu *);
+       void (*vgpu_destroy)(struct intel_vgpu *vgpu);
+       void (*vgpu_release)(struct intel_vgpu *vgpu);
        void (*vgpu_reset)(struct intel_vgpu *);
        void (*vgpu_activate)(struct intel_vgpu *);
        void (*vgpu_deactivate)(struct intel_vgpu *);
 
        if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1))
                return;
 
-       intel_gvt_ops->vgpu_deactivate(vgpu);
+       intel_gvt_ops->vgpu_release(vgpu);
 
        ret = vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_IOMMU_NOTIFY,
                                        &vgpu->vdev.iommu_notifier);
 
        kunmap(page);
 }
 
-static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask)
+void intel_vgpu_clean_workloads(struct intel_vgpu *vgpu,
+                               unsigned long engine_mask)
 {
        struct intel_vgpu_submission *s = &vgpu->submission;
        struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
                 * cleaned up during the resetting process later, so doing
                 * the workload clean up here doesn't have any impact.
                 **/
-               clean_workloads(vgpu, ENGINE_MASK(ring_id));
+               intel_vgpu_clean_workloads(vgpu, ENGINE_MASK(ring_id));
        }
 
        workload->complete(workload);
        if (!s->active)
                return;
 
-       clean_workloads(vgpu, engine_mask);
+       intel_vgpu_clean_workloads(vgpu, engine_mask);
        s->ops->reset(vgpu, engine_mask);
 }
 
 
 
 void intel_vgpu_destroy_workload(struct intel_vgpu_workload *workload);
 
+void intel_vgpu_clean_workloads(struct intel_vgpu *vgpu,
+                               unsigned long engine_mask);
+
 #endif
 
  * @vgpu: virtual GPU
  *
  * This function is called when user wants to deactivate a virtual GPU.
- * All virtual GPU runtime information will be destroyed.
+ * The virtual GPU will be stopped.
  *
  */
 void intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu)
        }
 
        intel_vgpu_stop_schedule(vgpu);
-       intel_vgpu_dmabuf_cleanup(vgpu);
 
        mutex_unlock(&vgpu->vgpu_lock);
 }
 
+/**
+ * intel_gvt_release_vgpu - release a virtual GPU
+ * @vgpu: virtual GPU
+ *
+ * This function is called when user wants to release a virtual GPU.
+ * The virtual GPU will be stopped and all runtime information will be
+ * destroyed.
+ *
+ */
+void intel_gvt_release_vgpu(struct intel_vgpu *vgpu)
+{
+       intel_gvt_deactivate_vgpu(vgpu);
+
+       mutex_lock(&vgpu->vgpu_lock);
+       intel_vgpu_clean_workloads(vgpu, ALL_ENGINES);
+       intel_vgpu_dmabuf_cleanup(vgpu);
+       mutex_unlock(&vgpu->vgpu_lock);
+}
+
 /**
  * intel_gvt_destroy_vgpu - destroy a virtual GPU
  * @vgpu: virtual GPU