/*
* drivers/media/video/tegra/nvavp/nvavp_dev.c
*
- * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
clock_disable_work);
channel_info = nvavp_get_channel_info(nvavp, NVAVP_VIDEO_CHANNEL);
- mutex_lock(&nvavp->open_lock);
mutex_lock(&channel_info->pushbuffer_lock);
+ mutex_lock(&nvavp->open_lock);
if (nvavp_check_idle(nvavp, NVAVP_VIDEO_CHANNEL) && nvavp->pending) {
nvavp->pending = false;
nvavp_clks_disable(nvavp);
}
}
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"read ucode firmware from '%s' (%d bytes)\n",
fw_ucode_file, nvavp_ucode_fw->size);
ptr = (void *)nvavp_ucode_fw->data;
if (strncmp((const char *)ptr, "NVAVPAPP", 8)) {
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"ucode hdr string mismatch\n");
ret = -EINVAL;
goto err_req_ucode;
goto err_req_fw;
}
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"read firmware from '%s' (%d bytes)\n",
fw_os_file, nvavp_os_fw->size);
ptr = (void *)nvavp_os_fw->data;
if (strncmp((const char *)ptr, "NVAVP-OS", 8)) {
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"os hdr string mismatch\n");
ret = -EINVAL;
goto err_os_bin;
memcpy(os_info->os_bin, ptr, os_info->size);
memset(os_info->data + os_info->size, 0, SZ_1M - os_info->size);
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"entry=%08x control=%08x debug=%08x size=%d\n",
os_info->entry_offset, os_info->control_offset,
os_info->debug_offset, os_info->size);
memcpy(os_info->data, os_info->os_bin, os_info->size);
os_info->reset_addr = os_info->phys + os_info->entry_offset;
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"AVP os at vaddr=%p paddr=%llx reset_addr=%llx\n",
os_info->data, (u64)(os_info->phys), (u64)os_info->reset_addr);
return 0;
#if defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU) /* Tegra2 with AVP MMU */
/* paddr is phys address */
/* vaddr is AVP_KERNEL_VIRT_BASE */
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"using AVP MMU to relocate AVP os\n");
sprintf(fw_os_file, "nvavp_os.bin");
nvavp->os_info.reset_addr = AVP_KERNEL_VIRT_BASE;
#elif defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU) /* Tegra3 with SMMU */
/* paddr is any address behind SMMU */
/* vaddr is TEGRA_SMMU_BASE */
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"using SMMU at %lx to load AVP kernel\n",
(unsigned long)nvavp->os_info.phys);
BUG_ON(nvavp->os_info.phys != 0xeff00000
(unsigned long)nvavp->os_info.phys);
nvavp->os_info.reset_addr = nvavp->os_info.phys;
#else /* nvmem= carveout */
- dev_info(&nvavp->nvhost_dev->dev,
+ dev_dbg(&nvavp->nvhost_dev->dev,
"using nvmem= carveout at %llx to load AVP os\n",
(u64)nvavp->os_info.phys);
sprintf(fw_os_file, "nvavp_os_%08llx.bin", (u64)nvavp->os_info.phys);
if (!hdr.cmdbuf.mem)
return 0;
+ if (hdr.num_relocs > NVAVP_MAX_RELOCATION_COUNT) {
+ dev_err(&nvavp->nvhost_dev->dev,
+ "invalid num_relocs %d\n", hdr.num_relocs);
+ return -EINVAL;
+ }
+
if (copy_from_user(clientctx->relocs, (void __user *)hdr.relocs,
sizeof(struct nvavp_reloc) * hdr.num_relocs)) {
return -EFAULT;
return PTR_ERR(cmdbuf_dmabuf);
}
+ if ((hdr.cmdbuf.offset & 3)
+ || (hdr.cmdbuf.offset >= cmdbuf_dmabuf->size)) {
+ dev_err(&nvavp->nvhost_dev->dev,
+ "invalid cmdbuf offset %d\n", hdr.cmdbuf.offset);
+ ret = -EINVAL;
+ goto err_dmabuf_attach;
+ }
+
cmdbuf_attach = dma_buf_attach(cmdbuf_dmabuf, &nvavp->nvhost_dev->dev);
if (IS_ERR(cmdbuf_attach)) {
dev_err(&nvavp->nvhost_dev->dev, "cannot attach cmdbuf_dmabuf\n");
goto err_reloc_info;
}
+ if ((clientctx->relocs[i].cmdbuf_offset & 3)
+ || (clientctx->relocs[i].cmdbuf_offset >=
+ cmdbuf_dmabuf->size)
+ || (clientctx->relocs[i].cmdbuf_offset >=
+ (cmdbuf_dmabuf->size - hdr.cmdbuf.offset))) {
+ dev_err(&nvavp->nvhost_dev->dev,
+ "invalid reloc offset in cmdbuf %d\n",
+ clientctx->relocs[i].cmdbuf_offset);
+ ret = -EINVAL;
+ goto err_reloc_info;
+ }
+
reloc_addr = cmdbuf_data +
(clientctx->relocs[i].cmdbuf_offset >> 2);
ret = PTR_ERR(target_dmabuf);
goto target_dmabuf_fail;
}
+
+ if ((clientctx->relocs[i].target_offset & 3)
+ || (clientctx->relocs[i].target_offset >=
+ target_dmabuf->size)) {
+ dev_err(&nvavp->nvhost_dev->dev,
+ "invalid target offset in reloc %d\n",
+ clientctx->relocs[i].target_offset);
+ ret = -EINVAL;
+ goto target_attach_fail;
+ }
+
target_attach = dma_buf_attach(target_dmabuf,
&nvavp->nvhost_dev->dev);
if (IS_ERR(target_attach)) {
if (nvavp->refcount > 0)
nvavp->refcount--;
- if (!nvavp->refcount)
+ if (!nvavp->refcount) {
+ mutex_unlock(&nvavp->open_lock);
nvavp_uninit(nvavp);
+ mutex_lock(&nvavp->open_lock);
+ }
if (IS_VIDEO_CHANNEL_ID(channel_id))
nvavp->video_refcnt--;