diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 3a2a4164b4e4..aef69c92b51c 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -997,7 +997,7 @@ static int fastrpc_minidump_remove_region(struct fastrpc_mmap *map) static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache) { struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl; - int vmid, err = 0; + int vmid, err = 0, cid = -1; if (!fl) return; @@ -1036,7 +1036,16 @@ skip_buf_cache: goto bail; if (fl->sctx->smmu.cb) buf->phys &= ~((uint64_t)fl->sctx->smmu.cb << 32); - vmid = fl->apps->channel[fl->cid].vmid; + cid = fl->cid; + VERIFY(err, VALID_FASTRPC_CID(cid)); + if (err) { + err = -ECHRNG; + ADSPRPC_ERR( + "invalid channel 0x%zx set for session\n", + cid); + goto bail; + } + vmid = fl->apps->channel[cid].vmid; if (vmid) { int srcVM[2] = {VMID_HLOS, vmid}; int hyp_err = 0; @@ -1050,7 +1059,7 @@ skip_buf_cache: hyp_err, buf->phys, buf->size); } } - trace_fastrpc_dma_free(fl->cid, buf->phys, buf->size); + trace_fastrpc_dma_free(cid, buf->phys, buf->size); dma_free_attrs(fl->sctx->smmu.dev, buf->size, buf->virt, buf->phys, buf->dma_attr); } @@ -1304,7 +1313,7 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags) (dma_addr_t)map->phys, (unsigned long)map->attr); } } else if (map->flags == FASTRPC_DMAHANDLE_NOMAP) { - trace_fastrpc_dma_unmap(fl->cid, map->phys, map->size); + trace_fastrpc_dma_unmap(cid, map->phys, map->size); if (!IS_ERR_OR_NULL(map->table)) dma_buf_unmap_attachment(map->attach, map->table, DMA_BIDIRECTIONAL); @@ -1321,7 +1330,7 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags) else sess = fl->sctx; - vmid = fl->apps->channel[fl->cid].vmid; + vmid = fl->apps->channel[cid].vmid; if (vmid && map->phys) { int hyp_err = 0; int srcVM[2] = {VMID_HLOS, vmid}; @@ -1335,7 +1344,7 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags) hyp_err, map->phys, map->size); } } - trace_fastrpc_dma_unmap(fl->cid, map->phys, map->size); + trace_fastrpc_dma_unmap(cid, map->phys, map->size); if (!IS_ERR_OR_NULL(map->table)) dma_buf_unmap_attachment(map->attach, map->table, DMA_BIDIRECTIONAL); @@ -1389,6 +1398,11 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, int err = 0, vmid, sgl_index = 0; struct scatterlist *sgl = NULL; + if (!fl) { + err = -EBADF; + goto bail; + } + cid = fl->cid; VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS); if (err) { err = -ECHRNG; @@ -1485,7 +1499,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, } map->phys = sg_dma_address(map->table->sgl); map->size = len; - trace_fastrpc_dma_map(fl->cid, fd, map->phys, map->size, + trace_fastrpc_dma_map(cid, fd, map->phys, map->size, len, mflags, map->attach->dma_map_attrs); } else { if (map->attr && (map->attr & FASTRPC_ATTR_KEEP_MAP)) { @@ -1591,7 +1605,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, } else { map->size = buf_page_size(len); } - trace_fastrpc_dma_map(fl->cid, fd, map->phys, map->size, + trace_fastrpc_dma_map(cid, fd, map->phys, map->size, len, mflags, map->attach->dma_map_attrs); VERIFY(err, map->size >= len && map->size < me->max_size_limit); @@ -1602,7 +1616,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, goto bail; } - vmid = fl->apps->channel[fl->cid].vmid; + vmid = fl->apps->channel[cid].vmid; if (vmid) { int srcVM[1] = {VMID_HLOS}; int destVM[2] = {VMID_HLOS, vmid}; @@ -1702,7 +1716,7 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size, unsigned long dma_attr, uint32_t rflags, int buf_type, struct fastrpc_buf **obuf) { - int err = 0, vmid; + int err = 0, vmid, cid = -1; struct fastrpc_apps *me = &gfa; struct fastrpc_buf *buf = NULL; @@ -1719,6 +1733,13 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size, err = -EBADR; goto bail; } + cid = fl->cid; + VERIFY(err, VALID_FASTRPC_CID(cid)); + if (err) { + err = -ECHRNG; + goto bail; + } + VERIFY(err, size > 0 && fl->sctx->smmu.dev); if (err) { err = (fl->sctx->smmu.dev == NULL) ? -ENODEV : err; @@ -1766,10 +1787,10 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size, } if (fl->sctx->smmu.cb) buf->phys += ((uint64_t)fl->sctx->smmu.cb << 32); - trace_fastrpc_dma_alloc(fl->cid, buf->phys, size, + trace_fastrpc_dma_alloc(cid, buf->phys, size, dma_attr, (int)rflags); - vmid = fl->apps->channel[fl->cid].vmid; + vmid = fl->apps->channel[cid].vmid; if (vmid) { int srcVM[1] = {VMID_HLOS}; int destVM[2] = {VMID_HLOS, vmid}; @@ -2940,6 +2961,10 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, uint32_t sc = ctx->sc; int64_t ns = 0; + if (!fl) { + err = -EBADF; + goto bail; + } cid = fl->cid; VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS); if (err) { @@ -2947,7 +2972,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, goto bail; } - channel_ctx = &fl->apps->channel[fl->cid]; + channel_ctx = &fl->apps->channel[cid]; mutex_lock(&channel_ctx->smd_mutex); msg->pid = fl->tgid; msg->tid = current->pid; @@ -2977,7 +3002,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, } err = rpmsg_send(channel_ctx->rpdev->ept, (void *)msg, sizeof(*msg)); mutex_unlock(&channel_ctx->rpmsg_mutex); - trace_fastrpc_rpmsg_send(fl->cid, (uint64_t)ctx, msg->invoke.header.ctx, + trace_fastrpc_rpmsg_send(cid, (uint64_t)ctx, msg->invoke.header.ctx, handle, sc, msg->invoke.page.addr, msg->invoke.page.size); ns = get_timestamp_in_ns(); fastrpc_update_txmsg_buf(channel_ctx, msg, err, ns); @@ -4116,21 +4141,29 @@ bail: static int fastrpc_send_cpuinfo_to_dsp(struct fastrpc_file *fl) { - int err = 0; + int err = 0, cid = -1; uint64_t cpuinfo = 0; struct fastrpc_apps *me = &gfa; struct fastrpc_ioctl_invoke_async ioctl; remote_arg_t ra[2]; - VERIFY(err, fl && fl->cid >= ADSP_DOMAIN_ID && fl->cid < NUM_CHANNELS); + if (!fl) { + err = -EBADF; + goto bail; + } + cid = fl->cid; + VERIFY(err, VALID_FASTRPC_CID(cid)); if (err) { err = -ECHRNG; + ADSPRPC_ERR( + "invalid channel 0x%zx set for session\n", + cid); goto bail; } - cpuinfo = me->channel[fl->cid].cpuinfo_todsp; + cpuinfo = me->channel[cid].cpuinfo_todsp; /* return success if already updated to remote processor */ - if (me->channel[fl->cid].cpuinfo_status) + if (me->channel[cid].cpuinfo_status) return 0; ra[0].buf.pv = (void *)&cpuinfo; @@ -4148,7 +4181,7 @@ static int fastrpc_send_cpuinfo_to_dsp(struct fastrpc_file *fl) err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, KERNEL_MSG_WITH_ZERO_PID, &ioctl); if (!err) - me->channel[fl->cid].cpuinfo_status = true; + me->channel[cid].cpuinfo_status = true; bail: return err; } @@ -4263,12 +4296,17 @@ bail: static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) { - int err = 0; + int err = 0, cid = -1; struct fastrpc_ioctl_invoke_async ioctl; remote_arg_t ra[1]; int tgid = 0; - VERIFY(err, fl->cid >= ADSP_DOMAIN_ID && fl->cid < NUM_CHANNELS); + if (!fl) { + err = -EBADF; + goto bail; + } + cid = fl->cid; + VERIFY(err, VALID_FASTRPC_CID(cid)); if (err) { err = -ECHRNG; goto bail; @@ -4278,12 +4316,12 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) err = -EBADR; goto bail; } - VERIFY(err, fl->apps->channel[fl->cid].rpdev != NULL); + VERIFY(err, fl->apps->channel[cid].rpdev != NULL); if (err) { err = -ENODEV; goto bail; } - VERIFY(err, fl->apps->channel[fl->cid].issubsystemup == 1); + VERIFY(err, fl->apps->channel[cid].issubsystemup == 1); if (err) { err = -ECONNRESET; goto bail; @@ -4470,7 +4508,7 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags, struct fastrpc_ioctl_invoke_async ioctl; struct fastrpc_apps *me = &gfa; struct smq_phy_page page; - int num = 1; + int num = 1, cid = -1; remote_arg_t ra[3]; int err = 0; struct { @@ -4483,6 +4521,11 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags, uintptr_t vaddrout; } routargs; + if (!fl) { + err = -EBADF; + goto bail; + } + cid = fl->cid; inargs.pid = fl->tgid; inargs.vaddrin = (uintptr_t)va; inargs.flags = flags; @@ -4514,12 +4557,22 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags, *raddr = (uintptr_t)routargs.vaddrout; if (err) goto bail; + if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) { + VERIFY(err, VALID_FASTRPC_CID(cid)); + if (err) { + err = -ECHRNG; + ADSPRPC_ERR( + "invalid channel 0x%zx set for session\n", + cid); + goto bail; + } + } if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR - && me->channel[fl->cid].rhvm.vmid) { + && me->channel[cid].rhvm.vmid) { err = hyp_assign_phys(phys, (uint64_t)size, - hlosvm, 1, me->channel[fl->cid].rhvm.vmid, - me->channel[fl->cid].rhvm.vmperm, - me->channel[fl->cid].rhvm.vmcount); + hlosvm, 1, me->channel[cid].rhvm.vmid, + me->channel[cid].rhvm.vmperm, + me->channel[cid].rhvm.vmcount); if (err) { ADSPRPC_ERR( "rh hyp assign failed with %d for phys 0x%llx, size %zu\n", @@ -4542,7 +4595,7 @@ bail: static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys, size_t size, uint32_t flags) { - int err = 0; + int err = 0, cid = -1; struct fastrpc_apps *me = &gfa; int tgid = 0; int destVM[1] = {VMID_HLOS}; @@ -4556,8 +4609,20 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys, uint8_t skey; } routargs; - if (fl == NULL) + if (!fl) { + err = -EBADF; goto bail; + } + + cid = fl->cid; + VERIFY(err, VALID_FASTRPC_CID(cid)); + if (err) { + err = -ECHRNG; + ADSPRPC_ERR( + "invalid channel 0x%zx set for session\n", + cid); + goto bail; + } tgid = fl->tgid; ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); @@ -4679,6 +4744,10 @@ static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl) struct fastrpc_apps *me = &gfa; int session = 0, err = 0, cid = -1; + if (!fl) { + err = -EBADF; + goto bail; + } err = fastrpc_get_spd_session(fl->servloc_name, &session, &cid); if (err) @@ -4688,18 +4757,18 @@ static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl) err = -EBADR; goto bail; } - if (!me->channel[fl->cid].spd[session].ispdup) { + if (!me->channel[cid].spd[session].ispdup) { err = -ENOTCONN; goto bail; } - if (me->channel[fl->cid].spd[session].pdrcount != - me->channel[fl->cid].spd[session].prevpdrcount) { + if (me->channel[cid].spd[session].pdrcount != + me->channel[cid].spd[session].prevpdrcount) { err = fastrpc_mmap_remove_ssr(fl); if (err) ADSPRPC_WARN("failed to unmap remote heap (err %d)\n", err); - me->channel[fl->cid].spd[session].prevpdrcount = - me->channel[fl->cid].spd[session].pdrcount; + me->channel[cid].spd[session].prevpdrcount = + me->channel[cid].spd[session].pdrcount; } bail: return err; @@ -5246,7 +5315,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) struct hlist_node *n = NULL; struct fastrpc_mmap *map = NULL, *lmap = NULL; unsigned long flags; - int cid; + int cid = -1, err = 0; if (!fl) return 0; @@ -5305,6 +5374,7 @@ skip_dump_wait: } while (lmap); mutex_unlock(&fl->map_mutex); + VERIFY(err, VALID_FASTRPC_CID(cid)); if (fl->sctx) fastrpc_session_free(&fl->apps->channel[cid], fl->sctx); if (fl->secsctx)