drm/i915/gvt: free VFIO region space in vgpu detach
authorHang Yuan <hang.yuan@linux.intel.com>
Mon, 14 Jan 2019 10:43:39 +0000 (18:43 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Tue, 15 Jan 2019 10:28:15 +0000 (18:28 +0800)
VFIO region space is allocated when one region is registered for
one vgpu. So free the space when destroy the vgpu.

Also change the parameter of detach_vgpu callback to use vgpu directly.

Fixes: b851adeac0858c7d257b3 ("drm/i915/gvt: Add opregion support")
Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Hang Yuan <hang.yuan@linux.intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/hypercall.h
drivers/gpu/drm/i915/gvt/kvmgt.c
drivers/gpu/drm/i915/gvt/mpt.h

index 5af11cf1b48235c46079f376686112c5234abbfd..e1675a00df1269913ff73de8ab5ea17b20f6bb9e 100644 (file)
@@ -41,7 +41,7 @@ struct intel_gvt_mpt {
        int (*host_init)(struct device *dev, void *gvt, const void *ops);
        void (*host_exit)(struct device *dev, void *gvt);
        int (*attach_vgpu)(void *vgpu, unsigned long *handle);
-       void (*detach_vgpu)(unsigned long handle);
+       void (*detach_vgpu)(void *vgpu);
        int (*inject_msi)(unsigned long handle, u32 addr, u16 data);
        unsigned long (*from_virt_to_mfn)(void *p);
        int (*enable_page_track)(unsigned long handle, u64 gfn);
index c1072143da1dc3968767b94573383d3b06f25883..a3ee6b7c3cfc4a34e025fbd6a1ec45e120672605 100644 (file)
@@ -1662,9 +1662,21 @@ static int kvmgt_attach_vgpu(void *vgpu, unsigned long *handle)
        return 0;
 }
 
-static void kvmgt_detach_vgpu(unsigned long handle)
+static void kvmgt_detach_vgpu(void *p_vgpu)
 {
-       /* nothing to do here */
+       int i;
+       struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+
+       if (!vgpu->vdev.region)
+               return;
+
+       for (i = 0; i < vgpu->vdev.num_regions; i++)
+               if (vgpu->vdev.region[i].ops->release)
+                       vgpu->vdev.region[i].ops->release(vgpu,
+                                       &vgpu->vdev.region[i]);
+       vgpu->vdev.num_regions = 0;
+       kfree(vgpu->vdev.region);
+       vgpu->vdev.region = NULL;
 }
 
 static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data)
index 67f19992b226f29a13d408be36da8b4820095b13..3ed34123d8d1373e10687665d1a03cb91380d6b5 100644 (file)
@@ -101,7 +101,7 @@ static inline void intel_gvt_hypervisor_detach_vgpu(struct intel_vgpu *vgpu)
        if (!intel_gvt_host.mpt->detach_vgpu)
                return;
 
-       intel_gvt_host.mpt->detach_vgpu(vgpu->handle);
+       intel_gvt_host.mpt->detach_vgpu(vgpu);
 }
 
 #define MSI_CAP_CONTROL(offset) (offset + 2)