diff options
author | Xiong Zhang <xiong.y.zhang@intel.com> | 2018-04-13 10:26:16 +0800 |
---|---|---|
committer | Zhenyu Wang <zhenyuw@linux.intel.com> | 2018-04-16 17:24:04 +0800 |
commit | d54e79340ff8d65b6c63ac278158add2fe211fd0 (patch) | |
tree | 1a8e8b30c8c880465cbbdf2ca013c11e5fcfdfbe /drivers/gpu/drm/i915 | |
parent | 2f24636b4b12e4f1eca23e6e5dd86ba335fc8066 (diff) | |
download | op-kernel-dev-d54e79340ff8d65b6c63ac278158add2fe211fd0.zip op-kernel-dev-d54e79340ff8d65b6c63ac278158add2fe211fd0.tar.gz |
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>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/gvt/kvmgt.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 021f722..a7487f4 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -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; |