Make sure elemcnt does not exceed the maximum element count in
virtio_gpu_queue_ctrl_sgs.  We should improve our error handling or
impose a size limit on execbuffer, which are TODOs.

Signed-off-by: Chia-I Wu <olva...@gmail.com>
Cc: David Riley <davidri...@chromium.org>
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   | 1 +
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 +++
 drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 ++
 drivers/gpu/drm/virtio/virtgpu_vq.c    | 2 +-
 4 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 7e69c06e168ea..f7520feb39d4b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -143,6 +143,7 @@ struct virtio_gpu_framebuffer {
 
 struct virtio_gpu_queue {
        struct virtqueue *vq;
+       unsigned int max_free;
        spinlock_t qlock;
        wait_queue_head_t ack_queue;
        struct work_struct dequeue_work;
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 205ec4abae2b9..0954f61d2000f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -132,6 +132,9 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device 
*dev, void *data,
                        goto out_unused_fd;
        }
 
+       /* XXX virtio_gpu_cmd_submit may fail silently when exbuf->size is
+        * huge
+        */
        buf = vmemdup_user(u64_to_user_ptr(exbuf->command), exbuf->size);
        if (IS_ERR(buf)) {
                ret = PTR_ERR(buf);
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c 
b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 2f5773e43557c..e7d5840e432dc 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -170,7 +170,9 @@ int virtio_gpu_init(struct drm_device *dev)
                goto err_vqs;
        }
        vgdev->ctrlq.vq = vqs[0];
+       vgdev->ctrlq.max_free = vqs[0]->num_free;
        vgdev->cursorq.vq = vqs[1];
+       vgdev->cursorq.max_free = vqs[1]->num_free;
        ret = virtio_gpu_alloc_vbufs(vgdev);
        if (ret) {
                DRM_ERROR("failed to alloc vbufs\n");
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c 
b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 0bf82cff8da37..725cfe93bcef8 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -333,7 +333,7 @@ static bool virtio_gpu_queue_ctrl_sgs(struct 
virtio_gpu_device *vgdev,
 again:
        spin_lock(&vgdev->ctrlq.qlock);
 
-       if (!vgdev->vqs_ready) {
+       if (unlikely(!vgdev->vqs_ready || elemcnt > vgdev->ctrlq.max_free)) {
                spin_unlock(&vgdev->ctrlq.qlock);
 
                if (fence && vbuf->objs)
-- 
2.25.0.341.g760bfbb309-goog

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to