summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/gvt
diff options
context:
space:
mode:
authorXiaolin Zhang2019-07-17 19:10:24 +0200
committerGreg Kroah-Hartman2019-08-06 19:06:56 +0200
commita7340d31abacf60efb68b299829c85e171878eae (patch)
treeb22c66e310c86c1ef86869e2ca3e5764a8c11d55 /drivers/gpu/drm/i915/gvt
parentIB/hfi1: Check for error on call to alloc_rsm_map_table (diff)
downloadkernel-qcow2-linux-a7340d31abacf60efb68b299829c85e171878eae.tar.gz
kernel-qcow2-linux-a7340d31abacf60efb68b299829c85e171878eae.tar.xz
kernel-qcow2-linux-a7340d31abacf60efb68b299829c85e171878eae.zip
drm/i915/gvt: fix incorrect cache entry for guest page mapping
commit 7366aeb77cd840f3edea02c65065d40affaa7f45 upstream. GPU hang observed during the guest OCL conformance test which is caused by THP GTT feature used durning the test. It was observed the same GFN with different size (4K and 2M) requested from the guest in GVT. So during the guest page dma map stage, it is required to unmap first with orginal size and then remap again with requested size. Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") Cc: stable@vger.kernel.org Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Xiaolin Zhang <xiaolin.zhang@intel.com> Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu/drm/i915/gvt')
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 12e4203c06db..66abe061f07b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1748,6 +1748,18 @@ int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,
ret = __gvt_cache_add(info->vgpu, gfn, *dma_addr, size);
if (ret)
goto err_unmap;
+ } else if (entry->size != size) {
+ /* the same gfn with different size: unmap and re-map */
+ gvt_dma_unmap_page(vgpu, gfn, entry->dma_addr, entry->size);
+ __gvt_cache_remove_entry(vgpu, entry);
+
+ ret = gvt_dma_map_page(vgpu, gfn, dma_addr, size);
+ if (ret)
+ goto err_unlock;
+
+ ret = __gvt_cache_add(info->vgpu, gfn, *dma_addr, size);
+ if (ret)
+ goto err_unmap;
} else {
kref_get(&entry->ref);
*dma_addr = entry->dma_addr;