Commit 6a37c49a authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Gerd Hoffmann

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: default avatarMatthew Wilcox <willy@infradead.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20180926160031.15721-3-willy@infradead.orgSigned-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 1938d1ae
...@@ -52,31 +52,22 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) ...@@ -52,31 +52,22 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work)
events_clear, &events_clear); events_clear, &events_clear);
} }
static void virtio_gpu_ctx_id_get(struct virtio_gpu_device *vgdev, static int virtio_gpu_context_create(struct virtio_gpu_device *vgdev,
uint32_t *resid) uint32_t nlen, const char *name)
{ {
int handle = ida_alloc_min(&vgdev->ctx_id_ida, 1, GFP_KERNEL); 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) if (handle < 0)
{ return handle;
ida_free(&vgdev->ctx_id_ida, id); virtio_gpu_cmd_context_create(vgdev, handle, nlen, name);
} return handle;
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);
} }
static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev, static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev,
uint32_t ctx_id) uint32_t ctx_id)
{ {
virtio_gpu_cmd_context_destroy(vgdev, 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, 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) ...@@ -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_device *vgdev = dev->dev_private;
struct virtio_gpu_fpriv *vfpriv; struct virtio_gpu_fpriv *vfpriv;
uint32_t id; int id;
char dbgname[TASK_COMM_LEN]; char dbgname[TASK_COMM_LEN];
/* can't create contexts without 3d renderer */ /* can't create contexts without 3d renderer */
...@@ -274,7 +265,9 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) ...@@ -274,7 +265,9 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file)
return -ENOMEM; return -ENOMEM;
get_task_comm(dbgname, current); 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; vfpriv->ctx_id = id;
file->driver_priv = vfpriv; file->driver_priv = vfpriv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment