summaryrefslogtreecommitdiff
path: root/drivers/media/platform/tegra/nvavp/nvavp_dev.c
diff options
context:
space:
mode:
authorSoumen Kumar Dey <sdey@nvidia.com>2016-06-14 14:31:57 +0530
committerMatthew Pedro <mapedro@nvidia.com>2016-09-15 09:18:03 -0700
commitff94d4ba6858af3861eb902c5677aed0acfc01fe (patch)
tree5aae5886b9e3319f5dd7e8d2e7eb188635e6bdb7 /drivers/media/platform/tegra/nvavp/nvavp_dev.c
parentcd9b8bf34e7d601896c8c019b956feddf56871d6 (diff)
nvavp: Add mutex lock for all avp submit
Add mutex lock for nvavp_submit to avoid race condition. bug 1775299 Change-Id: I11a66a58a1f048d6a0ee5aa949f852bfef56dc07 Signed-off-by: Soumen Kumar Dey <sdey@nvidia.com> Reviewed-on: http://git-master/r/1164117 (cherry picked from commit 1faa6a739996fdacff3dbc85ad46235f42ad79c9) Reviewed-on: http://git-master/r/1214643 GVS: Gerrit_Virtual_Submit Reviewed-by: Matthew Pedro <mapedro@nvidia.com>
Diffstat (limited to 'drivers/media/platform/tegra/nvavp/nvavp_dev.c')
-rw-r--r--drivers/media/platform/tegra/nvavp/nvavp_dev.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/drivers/media/platform/tegra/nvavp/nvavp_dev.c b/drivers/media/platform/tegra/nvavp/nvavp_dev.c
index 05c5f997e12f..cc98f192d086 100644
--- a/drivers/media/platform/tegra/nvavp/nvavp_dev.c
+++ b/drivers/media/platform/tegra/nvavp/nvavp_dev.c
@@ -135,6 +135,7 @@ struct nvavp_info {
int mbox_from_avp_pend_irq;
struct mutex open_lock;
+ struct mutex submit_lock;
int refcount;
int video_initialized;
int video_refcnt;
@@ -1521,15 +1522,20 @@ static int nvavp_pushbuffer_submit_ioctl(struct file *filp, unsigned int cmd,
syncpt.id = NVSYNCPT_INVALID;
syncpt.value = 0;
+ mutex_lock(&nvavp->submit_lock);
if (_IOC_DIR(cmd) & _IOC_WRITE) {
if (copy_from_user(&hdr, (void __user *)arg,
- sizeof(struct nvavp_pushbuffer_submit_hdr)))
+ sizeof(struct nvavp_pushbuffer_submit_hdr))) {
+ mutex_unlock(&nvavp->submit_lock);
return -EFAULT;
+ }
}
- if (!hdr.cmdbuf.mem)
+ if (!hdr.cmdbuf.mem) {
+ mutex_unlock(&nvavp->submit_lock);
return 0;
+ }
if (hdr.num_relocs > NVAVP_MAX_RELOCATION_COUNT) {
dev_err(&nvavp->nvhost_dev->dev,
@@ -1539,6 +1545,7 @@ static int nvavp_pushbuffer_submit_ioctl(struct file *filp, unsigned int cmd,
if (copy_from_user(clientctx->relocs, (void __user *)hdr.relocs,
sizeof(struct nvavp_reloc) * hdr.num_relocs)) {
+ mutex_unlock(&nvavp->submit_lock);
return -EFAULT;
}
@@ -1546,6 +1553,7 @@ static int nvavp_pushbuffer_submit_ioctl(struct file *filp, unsigned int cmd,
if (IS_ERR(cmdbuf_dmabuf)) {
dev_err(&nvavp->nvhost_dev->dev,
"invalid cmd buffer handle %08x\n", hdr.cmdbuf.mem);
+ mutex_unlock(&nvavp->submit_lock);
return PTR_ERR(cmdbuf_dmabuf);
}
@@ -1682,6 +1690,7 @@ err_dmabuf_map:
dma_buf_detach(cmdbuf_dmabuf, cmdbuf_attach);
err_dmabuf_attach:
dma_buf_put(cmdbuf_dmabuf);
+ mutex_unlock(&nvavp->submit_lock);
return ret;
}
@@ -1695,19 +1704,26 @@ static int nvavp_pushbuffer_submit_compat_ioctl(struct file *filp,
struct nvavp_pushbuffer_submit_hdr_v32 hdr_v32;
struct nvavp_pushbuffer_submit_hdr __user *user_hdr;
int ret = 0;
+ mutex_lock(&nvavp->submit_lock);
if (_IOC_DIR(cmd) & _IOC_WRITE) {
if (copy_from_user(&hdr_v32, (void __user *)arg,
- sizeof(struct nvavp_pushbuffer_submit_hdr_v32)))
+ sizeof(struct nvavp_pushbuffer_submit_hdr_v32))) {
+ mutex_unlock(&nvavp->submit_lock);
return -EFAULT;
+ }
}
- if (!hdr_v32.cmdbuf.mem)
+ if (!hdr_v32.cmdbuf.mem) {
+ mutex_unlock(&nvavp->submit_lock);
return 0;
+ }
user_hdr = compat_alloc_user_space(sizeof(*user_hdr));
- if (!access_ok(VERIFY_WRITE, user_hdr, sizeof(*user_hdr)))
+ if (!access_ok(VERIFY_WRITE, user_hdr, sizeof(*user_hdr))) {
+ mutex_unlock(&nvavp->submit_lock);
return -EFAULT;
+ }
if (__put_user(hdr_v32.cmdbuf.mem, &user_hdr->cmdbuf.mem)
|| __put_user(hdr_v32.cmdbuf.offset, &user_hdr->cmdbuf.offset)
@@ -1717,21 +1733,29 @@ static int nvavp_pushbuffer_submit_compat_ioctl(struct file *filp,
|| __put_user(hdr_v32.num_relocs, &user_hdr->num_relocs)
|| __put_user((void __user *)(unsigned long)hdr_v32.syncpt,
&user_hdr->syncpt)
- || __put_user(hdr_v32.flags, &user_hdr->flags))
+ || __put_user(hdr_v32.flags, &user_hdr->flags)) {
+ mutex_unlock(&nvavp->submit_lock);
return -EFAULT;
+ }
+ mutex_unlock(&nvavp->submit_lock);
ret = nvavp_pushbuffer_submit_ioctl(filp, cmd, (unsigned long)user_hdr);
if (ret)
return ret;
- if (__get_user(hdr_v32.syncpt, &user_hdr->syncpt))
+ mutex_lock(&nvavp->submit_lock);
+ if (__get_user(hdr_v32.syncpt, (uintptr_t *)&user_hdr->syncpt))
+ {
+ mutex_unlock(&nvavp->submit_lock);
return -EFAULT;
+ }
if (copy_to_user((void __user *)arg, &hdr_v32,
sizeof(struct nvavp_pushbuffer_submit_hdr_v32))) {
ret = -EFAULT;
}
+ mutex_unlock(&nvavp->submit_lock);
return ret;
}
#endif
@@ -2383,6 +2407,7 @@ static int tegra_nvavp_probe(struct platform_device *ndev)
nvavp->mbox_from_avp_pend_irq = irq;
mutex_init(&nvavp->open_lock);
+ mutex_init(&nvavp->submit_lock);
for (channel_id = 0; channel_id < NVAVP_NUM_CHANNELS; channel_id++)
mutex_init(&nvavp->channel_info[channel_id].pushbuffer_lock);