Merge tag 'drm-intel-next-2018-09-06-2' of git://anongit.freedesktop.org/drm/drm...
[linux-block.git] / drivers / gpu / drm / i915 / gvt / kvmgt.c
index a22d539b9d4e721884e605d0d4106277db4c6bf8..71751be329e3c58c323feae1c774696ff87aec9c 100644 (file)
@@ -43,6 +43,8 @@
 #include <linux/mdev.h>
 #include <linux/debugfs.h>
 
+#include <linux/nospec.h>
+
 #include "i915_drv.h"
 #include "gvt.h"
 
@@ -187,14 +189,14 @@ static int gvt_dma_map_page(struct intel_vgpu *vgpu, unsigned long gfn,
 
        /* Setup DMA mapping. */
        *dma_addr = dma_map_page(dev, page, 0, size, PCI_DMA_BIDIRECTIONAL);
-       ret = dma_mapping_error(dev, *dma_addr);
-       if (ret) {
+       if (dma_mapping_error(dev, *dma_addr)) {
                gvt_vgpu_err("DMA mapping failed for pfn 0x%lx, ret %d\n",
                             page_to_pfn(page), ret);
                gvt_unpin_guest_page(vgpu, gfn, size);
+               return -ENOMEM;
        }
 
-       return ret;
+       return 0;
 }
 
 static void gvt_dma_unmap_page(struct intel_vgpu *vgpu, unsigned long gfn,
@@ -666,7 +668,7 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
        if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1))
                return;
 
-       intel_gvt_ops->vgpu_deactivate(vgpu);
+       intel_gvt_ops->vgpu_release(vgpu);
 
        ret = vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_IOMMU_NOTIFY,
                                        &vgpu->vdev.iommu_notifier);
@@ -1139,7 +1141,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
        } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) {
                struct vfio_region_info info;
                struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
-               int i, ret;
+               unsigned int i;
+               int ret;
                struct vfio_region_info_cap_sparse_mmap *sparse = NULL;
                size_t size;
                int nr_areas = 1;
@@ -1224,6 +1227,10 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
                                if (info.index >= VFIO_PCI_NUM_REGIONS +
                                                vgpu->vdev.num_regions)
                                        return -EINVAL;
+                               info.index =
+                                       array_index_nospec(info.index,
+                                                       VFIO_PCI_NUM_REGIONS +
+                                                       vgpu->vdev.num_regions);
 
                                i = info.index - VFIO_PCI_NUM_REGIONS;
 
@@ -1250,11 +1257,13 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
                                        &sparse->header, sizeof(*sparse) +
                                        (sparse->nr_areas *
                                                sizeof(*sparse->areas)));
-                               kfree(sparse);
-                               if (ret)
+                               if (ret) {
+                                       kfree(sparse);
                                        return ret;
+                               }
                                break;
                        default:
+                               kfree(sparse);
                                return -EINVAL;
                        }
                }
@@ -1270,6 +1279,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
                                                  sizeof(info), caps.buf,
                                                  caps.size)) {
                                        kfree(caps.buf);
+                                       kfree(sparse);
                                        return -EFAULT;
                                }
                                info.cap_offset = sizeof(info);
@@ -1278,6 +1288,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
                        kfree(caps.buf);
                }
 
+               kfree(sparse);
                return copy_to_user((void __user *)arg, &info, minsz) ?
                        -EFAULT : 0;
        } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
@@ -1615,7 +1626,6 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
        kvmgt_protect_table_init(info);
        gvt_cache_init(vgpu);
 
-       mutex_init(&vgpu->dmabuf_lock);
        init_completion(&vgpu->vblank_done);
 
        info->track_node.track_write = kvmgt_page_track_write;