diff options
| -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 | ||
