Skip to content

Commit

Permalink
Merge tag 'gvt-fixes-2018-04-19' of https://github.com/intel/gvt-linux
Browse files Browse the repository at this point in the history
…into drm-intel-next-fixes

gvt-fixes-2018-04-19

- cmd parser error path mem leak fix (Colin)
- fix dp aux header validation (Changbin)
- sanity check on pfn after vfio pin page (Changbin)
- fix msi eventfd put (Xiong)

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180419073948.4mojv7xaxxvfuyud@zhen-hp.sh.intel.com
  • Loading branch information
Jani Nikula committed Jun 7, 2018
2 parents 197af5f + 39b4cba commit 807cba6
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 6 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/gvt/cmd_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2909,6 +2909,7 @@ static int init_cmd_table(struct intel_gvt *gvt)
if (info) {
gvt_err("%s %s duplicated\n", e->info->name,
info->name);
kfree(e);
return -EEXIST;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gvt/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
#define AUX_NATIVE_REPLY_NAK (0x1 << 4)
#define AUX_NATIVE_REPLY_DEFER (0x2 << 4)

#define AUX_BURST_SIZE 16
#define AUX_BURST_SIZE 20

/* DPCD addresses */
#define DPCD_REV 0x000
Expand Down
13 changes: 9 additions & 4 deletions drivers/gpu/drm/i915/gvt/handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -903,11 +903,14 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
}

/*
* Write request format: (command + address) occupies
* 3 bytes, followed by (len + 1) bytes of data.
* Write request format: Headr (command + address + size) occupies
* 4 bytes, followed by (len + 1) bytes of data. See details at
* intel_dp_aux_transfer().
*/
if (WARN_ON((len + 4) > AUX_BURST_SIZE))
if ((len + 1 + 4) > AUX_BURST_SIZE) {
gvt_vgpu_err("dp_aux_header: len %d is too large\n", len);
return -EINVAL;
}

/* unpack data from vreg to buf */
for (t = 0; t < 4; t++) {
Expand Down Expand Up @@ -971,8 +974,10 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
/*
* Read reply format: ACK (1 byte) plus (len + 1) bytes of data.
*/
if (WARN_ON((len + 2) > AUX_BURST_SIZE))
if ((len + 2) > AUX_BURST_SIZE) {
gvt_vgpu_err("dp_aux_header: len %d is too large\n", len);
return -EINVAL;
}

/* read from virtual DPCD to vreg */
/* first 4 bytes: [ACK][addr][addr+1][addr+2] */
Expand Down
34 changes: 33 additions & 1 deletion drivers/gpu/drm/i915/gvt/kvmgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ static int gvt_dma_map_page(struct intel_vgpu *vgpu, unsigned long gfn,
return -EINVAL;
}

if (!pfn_valid(pfn)) {
gvt_vgpu_err("pfn 0x%lx is not mem backed\n", pfn);
vfio_unpin_pages(mdev_dev(vgpu->vdev.mdev), &gfn, 1);
return -EINVAL;
}

/* Setup DMA mapping. */
page = pfn_to_page(pfn);
*dma_addr = dma_map_page(dev, page, 0, PAGE_SIZE,
Expand Down Expand Up @@ -583,6 +589,17 @@ static int intel_vgpu_open(struct mdev_device *mdev)
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;
Expand All @@ -607,6 +624,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;
}
Expand Down Expand Up @@ -987,7 +1006,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;
}
Expand Down Expand Up @@ -1592,6 +1612,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;

Expand Down

0 comments on commit 807cba6

Please sign in to comment.