diff options
author | Matthew Wilcox <willy@infradead.org> | 2018-09-26 19:00:29 +0300 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2018-10-30 00:50:55 +0300 |
commit | 6a37c49a94a95d4cd8ce4e7466f3bbb17e80ca64 (patch) | |
tree | 0a6b6d23e0056a6f635f36ec79f69b2b9c4bcaa6 | |
parent | 1938d1ae32fefa172288e3a9245ae126640c5c10 (diff) | |
download | linux-6a37c49a94a95d4cd8ce4e7466f3bbb17e80ca64.tar.xz |
drm/virtio: Handle context ID allocation errors
It is possible to run out of memory while allocating IDs. The current
code would create a context with an invalid ID; change it to return
-ENOMEM to userspace.
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20180926160031.15721-3-willy@infradead.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_kms.c | 29 |
1 files changed, 11 insertions, 18 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index e2604fe1b4ae..bf609dcae224 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -52,31 +52,22 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) events_clear, &events_clear); } -static void virtio_gpu_ctx_id_get(struct virtio_gpu_device *vgdev, - uint32_t *resid) +static int virtio_gpu_context_create(struct virtio_gpu_device *vgdev, + uint32_t nlen, const char *name) { int handle = ida_alloc_min(&vgdev->ctx_id_ida, 1, GFP_KERNEL); - *resid = handle; -} -static void virtio_gpu_ctx_id_put(struct virtio_gpu_device *vgdev, uint32_t id) -{ - ida_free(&vgdev->ctx_id_ida, id); -} - -static void virtio_gpu_context_create(struct virtio_gpu_device *vgdev, - uint32_t nlen, const char *name, - uint32_t *ctx_id) -{ - virtio_gpu_ctx_id_get(vgdev, ctx_id); - virtio_gpu_cmd_context_create(vgdev, *ctx_id, nlen, name); + if (handle < 0) + return handle; + virtio_gpu_cmd_context_create(vgdev, handle, nlen, name); + return handle; } static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev, uint32_t ctx_id) { virtio_gpu_cmd_context_destroy(vgdev, ctx_id); - virtio_gpu_ctx_id_put(vgdev, ctx_id); + ida_free(&vgdev->ctx_id_ida, ctx_id); } static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq, @@ -261,7 +252,7 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) { struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_fpriv *vfpriv; - uint32_t id; + int id; char dbgname[TASK_COMM_LEN]; /* can't create contexts without 3d renderer */ @@ -274,7 +265,9 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) return -ENOMEM; get_task_comm(dbgname, current); - virtio_gpu_context_create(vgdev, strlen(dbgname), dbgname, &id); + id = virtio_gpu_context_create(vgdev, strlen(dbgname), dbgname); + if (id < 0) + return id; vfpriv->ctx_id = id; file->driver_priv = vfpriv; |