Commit d54e7934 authored by Xiong Zhang's avatar Xiong Zhang Committed by Zhenyu Wang

drm/i915/gvt: Dereference msi eventfd_ctx when it isn't used anymore

kvmgt get msi eventfd_ctx at qemu vfio set irq eventfd, then
msi eventfd_ctx should be put at some point.
The first point is kvmgt handle qemu vfio_disable_irqindex()
call which has DATA_NONE and ACTION_TRIGGER in flags.
If qemu doesn't call vfio_disable_irqindex(), the second point
is vgpu release function.

v2: Don't inject msi interrupt into guest if eventfd_ctx is dereferenced
Signed-off-by: default avatarXiong Zhang <xiong.y.zhang@intel.com>
Reviewed-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
parent 2f24636b
...@@ -566,6 +566,17 @@ static int intel_vgpu_open(struct mdev_device *mdev) ...@@ -566,6 +566,17 @@ static int intel_vgpu_open(struct mdev_device *mdev)
return ret; return ret;
} }
static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu)
{
struct eventfd_ctx *trigger;
trigger = vgpu->vdev.msi_trigger;
if (trigger) {
eventfd_ctx_put(trigger);
vgpu->vdev.msi_trigger = NULL;
}
}
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;
...@@ -590,6 +601,8 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu) ...@@ -590,6 +601,8 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
info = (struct kvmgt_guest_info *)vgpu->handle; info = (struct kvmgt_guest_info *)vgpu->handle;
kvmgt_guest_exit(info); kvmgt_guest_exit(info);
intel_vgpu_release_msi_eventfd_ctx(vgpu);
vgpu->vdev.kvm = NULL; vgpu->vdev.kvm = NULL;
vgpu->handle = 0; vgpu->handle = 0;
} }
...@@ -970,7 +983,8 @@ static int intel_vgpu_set_msi_trigger(struct intel_vgpu *vgpu, ...@@ -970,7 +983,8 @@ static int intel_vgpu_set_msi_trigger(struct intel_vgpu *vgpu,
return PTR_ERR(trigger); return PTR_ERR(trigger);
} }
vgpu->vdev.msi_trigger = trigger; vgpu->vdev.msi_trigger = trigger;
} } else if ((flags & VFIO_IRQ_SET_DATA_NONE) && !count)
intel_vgpu_release_msi_eventfd_ctx(vgpu);
return 0; return 0;
} }
...@@ -1566,6 +1580,18 @@ static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data) ...@@ -1566,6 +1580,18 @@ static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data)
info = (struct kvmgt_guest_info *)handle; info = (struct kvmgt_guest_info *)handle;
vgpu = info->vgpu; vgpu = info->vgpu;
/*
* When guest is poweroff, msi_trigger is set to NULL, but vgpu's
* config and mmio register isn't restored to default during guest
* poweroff. If this vgpu is still used in next vm, this vgpu's pipe
* may be enabled, then once this vgpu is active, it will get inject
* vblank interrupt request. But msi_trigger is null until msi is
* enabled by guest. so if msi_trigger is null, success is still
* returned and don't inject interrupt into guest.
*/
if (vgpu->vdev.msi_trigger == NULL)
return 0;
if (eventfd_signal(vgpu->vdev.msi_trigger, 1) == 1) if (eventfd_signal(vgpu->vdev.msi_trigger, 1) == 1)
return 0; return 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