diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem_submit.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gem_submit.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 3c6bc90c3d48..5862db05297a 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -30,20 +30,17 @@ */ static struct msm_gem_submit *submit_create(struct drm_device *dev, - struct msm_gpu *gpu, + struct msm_gpu *gpu, struct drm_gpuvm *vm, struct msm_gpu_submitqueue *queue, uint32_t nr_bos, uint32_t nr_cmds, u64 drm_client_id) { static atomic_t ident = ATOMIC_INIT(0); struct msm_gem_submit *submit; - uint64_t sz; + size_t sz; int ret; - sz = struct_size(submit, bos, nr_bos) + - ((u64)nr_cmds * sizeof(submit->cmd[0])); - - if (sz > SIZE_MAX) - return ERR_PTR(-ENOMEM); + sz = size_add(struct_size(submit, bos, nr_bos), + array_size(sizeof(submit->cmd[0]), nr_cmds)); submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN); if (!submit) @@ -66,7 +63,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, kref_init(&submit->ref); submit->dev = dev; - submit->vm = msm_context_vm(dev, queue->ctx); + submit->vm = vm; submit->gpu = gpu; submit->cmd = (void *)&submit->bos[nr_bos]; submit->queue = queue; @@ -250,16 +247,14 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, sz = array_size(submit_cmd.nr_relocs, sizeof(struct drm_msm_gem_submit_reloc)); - /* check for overflow: */ - if (sz == SIZE_MAX) { - ret = -ENOMEM; - goto out; - } submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN); if (!submit->cmd[i].relocs) { ret = -ENOMEM; goto out; } + + submit->nr_cmds = i + 1; + ret = copy_from_user(submit->cmd[i].relocs, userptr, sz); if (ret) { ret = -EFAULT; @@ -554,6 +549,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct msm_drm_private *priv = dev->dev_private; struct drm_msm_gem_submit *args = data; struct msm_context *ctx = file->driver_priv; + struct drm_gpuvm *vm = msm_context_vm(dev, ctx); struct msm_gem_submit *submit = NULL; struct msm_gpu *gpu = priv->gpu; struct msm_gpu_submitqueue *queue; @@ -569,10 +565,13 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (!gpu) return -ENXIO; + if (!vm) + return UERR(ENOMEM, dev, "no VM"); + if (args->pad) return -EINVAL; - if (to_msm_vm(ctx->vm)->unusable) + if (to_msm_vm(vm)->unusable) return UERR(EPIPE, dev, "context is unusable"); /* for now, we just have 3d pipe.. eventually this would need to @@ -609,7 +608,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, } } - submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds, + submit = submit_create(dev, gpu, vm, queue, args->nr_bos, args->nr_cmds, file->client_id); if (IS_ERR(submit)) { ret = PTR_ERR(submit); @@ -719,8 +718,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, goto out; } - submit->nr_cmds = args->nr_cmds; - idr_preload(GFP_KERNEL); spin_lock(&queue->idr_lock); |
