Commit 364fb6b7 authored by Jike Song's avatar Jike Song Committed by Zhenyu Wang

drm/i915/gvt/kvmgt: prevent double-release of vgpu

The release action might be triggered from either user's closing
mdev or the detaching event of kvm and vfio_group, so this patch
introduces an atomic to prevent double-release.
Signed-off-by: default avatarJike Song <jike.song@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
parent faaaa53b
...@@ -175,6 +175,7 @@ struct intel_vgpu { ...@@ -175,6 +175,7 @@ struct intel_vgpu {
struct notifier_block group_notifier; struct notifier_block group_notifier;
struct kvm *kvm; struct kvm *kvm;
struct work_struct release_work; struct work_struct release_work;
atomic_t released;
} vdev; } vdev;
#endif #endif
}; };
......
...@@ -500,7 +500,16 @@ static int intel_vgpu_open(struct mdev_device *mdev) ...@@ -500,7 +500,16 @@ static int intel_vgpu_open(struct mdev_device *mdev)
goto undo_iommu; goto undo_iommu;
} }
return kvmgt_guest_init(mdev); ret = kvmgt_guest_init(mdev);
if (ret)
goto undo_group;
atomic_set(&vgpu->vdev.released, 0);
return ret;
undo_group:
vfio_unregister_notifier(&mdev->dev, VFIO_GROUP_NOTIFY,
&vgpu->vdev.group_notifier);
undo_iommu: undo_iommu:
vfio_unregister_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY, vfio_unregister_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY,
...@@ -512,17 +521,26 @@ static int intel_vgpu_open(struct mdev_device *mdev) ...@@ -512,17 +521,26 @@ static int intel_vgpu_open(struct mdev_device *mdev)
static void __intel_vgpu_release(struct intel_vgpu *vgpu) static void __intel_vgpu_release(struct intel_vgpu *vgpu)
{ {
struct kvmgt_guest_info *info; struct kvmgt_guest_info *info;
int ret;
if (!handle_valid(vgpu->handle)) if (!handle_valid(vgpu->handle))
return; return;
vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_IOMMU_NOTIFY, if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1))
return;
ret = vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_IOMMU_NOTIFY,
&vgpu->vdev.iommu_notifier); &vgpu->vdev.iommu_notifier);
vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_GROUP_NOTIFY, WARN(ret, "vfio_unregister_notifier for iommu failed: %d\n", ret);
ret = vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_GROUP_NOTIFY,
&vgpu->vdev.group_notifier); &vgpu->vdev.group_notifier);
WARN(ret, "vfio_unregister_notifier for group failed: %d\n", ret);
info = (struct kvmgt_guest_info *)vgpu->handle; info = (struct kvmgt_guest_info *)vgpu->handle;
kvmgt_guest_exit(info); kvmgt_guest_exit(info);
vgpu->vdev.kvm = NULL;
vgpu->handle = 0; vgpu->handle = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment