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: Xiong Zhang <xiong.y.zhang@intel.com> Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
This commit is contained in:
parent
2f24636b4b
commit
d54e79340f
|
@ -566,6 +566,17 @@ out:
|
|||
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)
|
||||
{
|
||||
struct kvmgt_guest_info *info;
|
||||
|
@ -590,6 +601,8 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
|
|||
info = (struct kvmgt_guest_info *)vgpu->handle;
|
||||
kvmgt_guest_exit(info);
|
||||
|
||||
intel_vgpu_release_msi_eventfd_ctx(vgpu);
|
||||
|
||||
vgpu->vdev.kvm = NULL;
|
||||
vgpu->handle = 0;
|
||||
}
|
||||
|
@ -970,7 +983,8 @@ static int intel_vgpu_set_msi_trigger(struct intel_vgpu *vgpu,
|
|||
return PTR_ERR(trigger);
|
||||
}
|
||||
vgpu->vdev.msi_trigger = trigger;
|
||||
}
|
||||
} else if ((flags & VFIO_IRQ_SET_DATA_NONE) && !count)
|
||||
intel_vgpu_release_msi_eventfd_ctx(vgpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1566,6 +1580,18 @@ static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data)
|
|||
info = (struct kvmgt_guest_info *)handle;
|
||||
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)
|
||||
return 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue