diff options
author | Jani Nikula <jani.nikula@intel.com> | 2018-06-07 05:06:07 -0400 |
---|---|---|
committer | Jani Nikula <jani.nikula@intel.com> | 2018-06-07 05:06:07 -0400 |
commit | 807cba6559cf333a74df1fbd74f0597e8e7fa020 (patch) | |
tree | b5f5260dd10caa3a9870b97ee4b86bda57d87d66 /drivers | |
parent | 197af5f2131101f9a6118b238901cb1988f5d7f9 (diff) | |
parent | 39b4cbadb9a95bf3f13ea102d6ec841940916ee2 (diff) |
Merge tag 'gvt-fixes-2018-04-19' of https://github.com/intel/gvt-linux 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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/gvt/cmd_parser.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/display.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/handlers.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/kvmgt.c | 34 |
4 files changed, 44 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 718ca08f9575..b51c05d03f14 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c | |||
@@ -2909,6 +2909,7 @@ static int init_cmd_table(struct intel_gvt *gvt) | |||
2909 | if (info) { | 2909 | if (info) { |
2910 | gvt_err("%s %s duplicated\n", e->info->name, | 2910 | gvt_err("%s %s duplicated\n", e->info->name, |
2911 | info->name); | 2911 | info->name); |
2912 | kfree(e); | ||
2912 | return -EEXIST; | 2913 | return -EEXIST; |
2913 | } | 2914 | } |
2914 | 2915 | ||
diff --git a/drivers/gpu/drm/i915/gvt/display.h b/drivers/gpu/drm/i915/gvt/display.h index b46b86892d58..ea7c1c525b8c 100644 --- a/drivers/gpu/drm/i915/gvt/display.h +++ b/drivers/gpu/drm/i915/gvt/display.h | |||
@@ -67,7 +67,7 @@ | |||
67 | #define AUX_NATIVE_REPLY_NAK (0x1 << 4) | 67 | #define AUX_NATIVE_REPLY_NAK (0x1 << 4) |
68 | #define AUX_NATIVE_REPLY_DEFER (0x2 << 4) | 68 | #define AUX_NATIVE_REPLY_DEFER (0x2 << 4) |
69 | 69 | ||
70 | #define AUX_BURST_SIZE 16 | 70 | #define AUX_BURST_SIZE 20 |
71 | 71 | ||
72 | /* DPCD addresses */ | 72 | /* DPCD addresses */ |
73 | #define DPCD_REV 0x000 | 73 | #define DPCD_REV 0x000 |
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 4b6532fb789a..bcbc47a88a70 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
@@ -903,11 +903,14 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu, | |||
903 | } | 903 | } |
904 | 904 | ||
905 | /* | 905 | /* |
906 | * Write request format: (command + address) occupies | 906 | * Write request format: Headr (command + address + size) occupies |
907 | * 3 bytes, followed by (len + 1) bytes of data. | 907 | * 4 bytes, followed by (len + 1) bytes of data. See details at |
908 | * intel_dp_aux_transfer(). | ||
908 | */ | 909 | */ |
909 | if (WARN_ON((len + 4) > AUX_BURST_SIZE)) | 910 | if ((len + 1 + 4) > AUX_BURST_SIZE) { |
911 | gvt_vgpu_err("dp_aux_header: len %d is too large\n", len); | ||
910 | return -EINVAL; | 912 | return -EINVAL; |
913 | } | ||
911 | 914 | ||
912 | /* unpack data from vreg to buf */ | 915 | /* unpack data from vreg to buf */ |
913 | for (t = 0; t < 4; t++) { | 916 | for (t = 0; t < 4; t++) { |
@@ -971,8 +974,10 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu, | |||
971 | /* | 974 | /* |
972 | * Read reply format: ACK (1 byte) plus (len + 1) bytes of data. | 975 | * Read reply format: ACK (1 byte) plus (len + 1) bytes of data. |
973 | */ | 976 | */ |
974 | if (WARN_ON((len + 2) > AUX_BURST_SIZE)) | 977 | if ((len + 2) > AUX_BURST_SIZE) { |
978 | gvt_vgpu_err("dp_aux_header: len %d is too large\n", len); | ||
975 | return -EINVAL; | 979 | return -EINVAL; |
980 | } | ||
976 | 981 | ||
977 | /* read from virtual DPCD to vreg */ | 982 | /* read from virtual DPCD to vreg */ |
978 | /* first 4 bytes: [ACK][addr][addr+1][addr+2] */ | 983 | /* first 4 bytes: [ACK][addr][addr+1][addr+2] */ |
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 1466d8769ec9..df4e4a07db3d 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c | |||
@@ -123,6 +123,12 @@ static int gvt_dma_map_page(struct intel_vgpu *vgpu, unsigned long gfn, | |||
123 | return -EINVAL; | 123 | return -EINVAL; |
124 | } | 124 | } |
125 | 125 | ||
126 | if (!pfn_valid(pfn)) { | ||
127 | gvt_vgpu_err("pfn 0x%lx is not mem backed\n", pfn); | ||
128 | vfio_unpin_pages(mdev_dev(vgpu->vdev.mdev), &gfn, 1); | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | |||
126 | /* Setup DMA mapping. */ | 132 | /* Setup DMA mapping. */ |
127 | page = pfn_to_page(pfn); | 133 | page = pfn_to_page(pfn); |
128 | *dma_addr = dma_map_page(dev, page, 0, PAGE_SIZE, | 134 | *dma_addr = dma_map_page(dev, page, 0, PAGE_SIZE, |
@@ -583,6 +589,17 @@ out: | |||
583 | return ret; | 589 | return ret; |
584 | } | 590 | } |
585 | 591 | ||
592 | static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu) | ||
593 | { | ||
594 | struct eventfd_ctx *trigger; | ||
595 | |||
596 | trigger = vgpu->vdev.msi_trigger; | ||
597 | if (trigger) { | ||
598 | eventfd_ctx_put(trigger); | ||
599 | vgpu->vdev.msi_trigger = NULL; | ||
600 | } | ||
601 | } | ||
602 | |||
586 | static void __intel_vgpu_release(struct intel_vgpu *vgpu) | 603 | static void __intel_vgpu_release(struct intel_vgpu *vgpu) |
587 | { | 604 | { |
588 | struct kvmgt_guest_info *info; | 605 | struct kvmgt_guest_info *info; |
@@ -607,6 +624,8 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu) | |||
607 | info = (struct kvmgt_guest_info *)vgpu->handle; | 624 | info = (struct kvmgt_guest_info *)vgpu->handle; |
608 | kvmgt_guest_exit(info); | 625 | kvmgt_guest_exit(info); |
609 | 626 | ||
627 | intel_vgpu_release_msi_eventfd_ctx(vgpu); | ||
628 | |||
610 | vgpu->vdev.kvm = NULL; | 629 | vgpu->vdev.kvm = NULL; |
611 | vgpu->handle = 0; | 630 | vgpu->handle = 0; |
612 | } | 631 | } |
@@ -987,7 +1006,8 @@ static int intel_vgpu_set_msi_trigger(struct intel_vgpu *vgpu, | |||
987 | return PTR_ERR(trigger); | 1006 | return PTR_ERR(trigger); |
988 | } | 1007 | } |
989 | vgpu->vdev.msi_trigger = trigger; | 1008 | vgpu->vdev.msi_trigger = trigger; |
990 | } | 1009 | } else if ((flags & VFIO_IRQ_SET_DATA_NONE) && !count) |
1010 | intel_vgpu_release_msi_eventfd_ctx(vgpu); | ||
991 | 1011 | ||
992 | return 0; | 1012 | return 0; |
993 | } | 1013 | } |
@@ -1592,6 +1612,18 @@ static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data) | |||
1592 | info = (struct kvmgt_guest_info *)handle; | 1612 | info = (struct kvmgt_guest_info *)handle; |
1593 | vgpu = info->vgpu; | 1613 | vgpu = info->vgpu; |
1594 | 1614 | ||
1615 | /* | ||
1616 | * When guest is poweroff, msi_trigger is set to NULL, but vgpu's | ||
1617 | * config and mmio register isn't restored to default during guest | ||
1618 | * poweroff. If this vgpu is still used in next vm, this vgpu's pipe | ||
1619 | * may be enabled, then once this vgpu is active, it will get inject | ||
1620 | * vblank interrupt request. But msi_trigger is null until msi is | ||
1621 | * enabled by guest. so if msi_trigger is null, success is still | ||
1622 | * returned and don't inject interrupt into guest. | ||
1623 | */ | ||
1624 | if (vgpu->vdev.msi_trigger == NULL) | ||
1625 | return 0; | ||
1626 | |||
1595 | if (eventfd_signal(vgpu->vdev.msi_trigger, 1) == 1) | 1627 | if (eventfd_signal(vgpu->vdev.msi_trigger, 1) == 1) |
1596 | return 0; | 1628 | return 0; |
1597 | 1629 | ||