If VIRTIO_GPU_F_BLOB_ALIGNMENT has been negotiated, both
CREATE_BLOB and MAP_BLOB requests must be aligned to blob_alignment.

Introduce checks to ensure we don't send invalid requests to the
device.

Signed-off-by: Sergio Lopez <[email protected]>
---
 drivers/gpu/drm/virtio/virtgpu_drv.h    |  2 +-
 drivers/gpu/drm/virtio/virtgpu_object.c |  6 ++++--
 drivers/gpu/drm/virtio/virtgpu_prime.c  |  7 +++++--
 drivers/gpu/drm/virtio/virtgpu_vq.c     | 12 +++++++++++-
 drivers/gpu/drm/virtio/virtgpu_vram.c   | 10 ++++++++--
 5 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index d1fa386a5a99..11a55d4ccd54 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -433,7 +433,7 @@ int virtio_gpu_cmd_map(struct virtio_gpu_device *vgdev,
 void virtio_gpu_cmd_unmap(struct virtio_gpu_device *vgdev,
                          struct virtio_gpu_object *bo);
 
-void
+int
 virtio_gpu_cmd_resource_create_blob(struct virtio_gpu_device *vgdev,
                                    struct virtio_gpu_object *bo,
                                    struct virtio_gpu_object_params *params,
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c 
b/drivers/gpu/drm/virtio/virtgpu_object.c
index e6363c887500..6118344bff84 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -246,8 +246,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
*vgdev,
                if (params->blob_mem == VIRTGPU_BLOB_MEM_GUEST)
                        bo->guest_blob = true;
 
-               virtio_gpu_cmd_resource_create_blob(vgdev, bo, params,
-                                                   ents, nents);
+               ret = virtio_gpu_cmd_resource_create_blob(vgdev, bo, params,
+                                                         ents, nents);
+               if (ret)
+                       goto err_put_objs;
        } else if (params->virgl) {
                virtio_gpu_cmd_resource_create_3d(vgdev, bo, params,
                                                  objs, fence);
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c 
b/drivers/gpu/drm/virtio/virtgpu_prime.c
index ce49282198cb..06593496c53f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -257,8 +257,11 @@ static int virtgpu_dma_buf_init_obj(struct drm_device *dev,
        params.blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE;
        params.size = attach->dmabuf->size;
 
-       virtio_gpu_cmd_resource_create_blob(vgdev, bo, &params,
-                                           ents, nents);
+       ret = virtio_gpu_cmd_resource_create_blob(vgdev, bo, &params,
+                                                 ents, nents);
+       if (ret)
+               goto err_import;
+
        bo->guest_blob = true;
 
        dma_buf_unpin(attach);
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c 
b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 8181b22b9b46..d558ba2d213a 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -1393,6 +1393,10 @@ int virtio_gpu_cmd_map(struct virtio_gpu_device *vgdev,
        struct virtio_gpu_vbuffer *vbuf;
        struct virtio_gpu_resp_map_info *resp_buf;
 
+       if (vgdev->has_blob_alignment &&
+           !IS_ALIGNED(offset, vgdev->blob_alignment))
+               return -EINVAL;
+
        resp_buf = kzalloc(sizeof(*resp_buf), GFP_KERNEL);
        if (!resp_buf)
                return -ENOMEM;
@@ -1426,7 +1430,7 @@ void virtio_gpu_cmd_unmap(struct virtio_gpu_device *vgdev,
        virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
 }
 
-void
+int
 virtio_gpu_cmd_resource_create_blob(struct virtio_gpu_device *vgdev,
                                    struct virtio_gpu_object *bo,
                                    struct virtio_gpu_object_params *params,
@@ -1436,6 +1440,10 @@ virtio_gpu_cmd_resource_create_blob(struct 
virtio_gpu_device *vgdev,
        struct virtio_gpu_resource_create_blob *cmd_p;
        struct virtio_gpu_vbuffer *vbuf;
 
+       if (vgdev->has_blob_alignment &&
+           !IS_ALIGNED(params->size, vgdev->blob_alignment))
+               return -EINVAL;
+
        cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
        memset(cmd_p, 0, sizeof(*cmd_p));
 
@@ -1456,6 +1464,8 @@ virtio_gpu_cmd_resource_create_blob(struct 
virtio_gpu_device *vgdev,
 
        if (nents)
                bo->attached = true;
+
+       return 0;
 }
 
 void virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev,
diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c 
b/drivers/gpu/drm/virtio/virtgpu_vram.c
index 5ad3b7c6f73c..6c402eca5726 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vram.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vram.c
@@ -216,8 +216,14 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev,
                return ret;
        }
 
-       virtio_gpu_cmd_resource_create_blob(vgdev, &vram->base, params, NULL,
-                                           0);
+       ret = virtio_gpu_cmd_resource_create_blob(vgdev, &vram->base, params,
+                                                 NULL, 0);
+       if (ret) {
+               drm_gem_free_mmap_offset(obj);
+               kfree(vram);
+               return ret;
+       }
+
        if (params->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE) {
                ret = virtio_gpu_vram_map(&vram->base);
                if (ret) {
-- 
2.51.0

Reply via email to