diff options
author | Xiong Zhang <xiong.y.zhang@intel.com> | 2018-04-12 22:26:16 -0400 |
---|---|---|
committer | Zhenyu Wang <zhenyuw@linux.intel.com> | 2018-04-16 05:24:04 -0400 |
commit | d54e79340ff8d65b6c63ac278158add2fe211fd0 (patch) | |
tree | 1a8e8b30c8c880465cbbdf2ca013c11e5fcfdfbe | |
parent | 2f24636b4b12e4f1eca23e6e5dd86ba335fc8066 (diff) |
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>
-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 021f722e2481..a7487f457508 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c | |||
@@ -566,6 +566,17 @@ out: | |||
566 | return ret; | 566 | return ret; |
567 | } | 567 | } |
568 | 568 | ||
569 | static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu) | ||
570 | { | ||
571 | struct eventfd_ctx *trigger; | ||
572 | |||
573 | trigger = vgpu->vdev.msi_trigger; | ||
574 | if (trigger) { | ||
575 | eventfd_ctx_put(trigger); | ||
576 | vgpu->vdev.msi_trigger = NULL; | ||
577 | } | ||
578 | } | ||
579 | |||
569 | static void __intel_vgpu_release(struct intel_vgpu *vgpu) | 580 | static void __intel_vgpu_release(struct intel_vgpu *vgpu) |
570 | { | 581 | { |
571 | struct kvmgt_guest_info *info; | 582 | struct kvmgt_guest_info *info; |
@@ -590,6 +601,8 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu) | |||
590 | info = (struct kvmgt_guest_info *)vgpu->handle; | 601 | info = (struct kvmgt_guest_info *)vgpu->handle; |
591 | kvmgt_guest_exit(info); | 602 | kvmgt_guest_exit(info); |
592 | 603 | ||
604 | intel_vgpu_release_msi_eventfd_ctx(vgpu); | ||
605 | |||
593 | vgpu->vdev.kvm = NULL; | 606 | vgpu->vdev.kvm = NULL; |
594 | vgpu->handle = 0; | 607 | vgpu->handle = 0; |
595 | } | 608 | } |
@@ -970,7 +983,8 @@ static int intel_vgpu_set_msi_trigger(struct intel_vgpu *vgpu, | |||
970 | return PTR_ERR(trigger); | 983 | return PTR_ERR(trigger); |
971 | } | 984 | } |
972 | vgpu->vdev.msi_trigger = trigger; | 985 | vgpu->vdev.msi_trigger = trigger; |
973 | } | 986 | } else if ((flags & VFIO_IRQ_SET_DATA_NONE) && !count) |
987 | intel_vgpu_release_msi_eventfd_ctx(vgpu); | ||
974 | 988 | ||
975 | return 0; | 989 | return 0; |
976 | } | 990 | } |
@@ -1566,6 +1580,18 @@ static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data) | |||
1566 | info = (struct kvmgt_guest_info *)handle; | 1580 | info = (struct kvmgt_guest_info *)handle; |
1567 | vgpu = info->vgpu; | 1581 | vgpu = info->vgpu; |
1568 | 1582 | ||
1583 | /* | ||
1584 | * When guest is poweroff, msi_trigger is set to NULL, but vgpu's | ||
1585 | * config and mmio register isn't restored to default during guest | ||
1586 | * poweroff. If this vgpu is still used in next vm, this vgpu's pipe | ||
1587 | * may be enabled, then once this vgpu is active, it will get inject | ||
1588 | * vblank interrupt request. But msi_trigger is null until msi is | ||
1589 | * enabled by guest. so if msi_trigger is null, success is still | ||
1590 | * returned and don't inject interrupt into guest. | ||
1591 | */ | ||
1592 | if (vgpu->vdev.msi_trigger == NULL) | ||
1593 | return 0; | ||
1594 | |||
1569 | if (eventfd_signal(vgpu->vdev.msi_trigger, 1) == 1) | 1595 | if (eventfd_signal(vgpu->vdev.msi_trigger, 1) == 1) |
1570 | return 0; | 1596 | return 0; |
1571 | 1597 | ||