Loading drivers/char/adsprpc.c +66 −11 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -66,6 +66,8 @@ #define NUM_CHANNELS 3 /*1 compute 1 cpz 1 mdsp*/ #define NUM_SESSIONS 8 /*8 compute*/ #define FASTRPC_CTX_MAGIC (0xbeeddeed) #define FASTRPC_CTX_MAX (256) #define FASTRPC_CTXID_MASK (0xFF0) #define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0) Loading Loading @@ -155,6 +157,7 @@ struct smq_invoke_ctx { struct overlap **overps; struct smq_msg msg; unsigned int magic; uint64_t ctxid; }; struct fastrpc_ctx_lst { Loading Loading @@ -218,6 +221,8 @@ struct fastrpc_apps { struct device *dev; struct device *modem_cma_dev; bool glink; spinlock_t ctxlock; struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX]; }; struct fastrpc_mmap { Loading Loading @@ -790,7 +795,8 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, struct fastrpc_ioctl_invoke_fd *invokefd, struct smq_invoke_ctx **po) { int err = 0, bufs, size = 0; int err = 0, bufs, ii, size = 0; struct fastrpc_apps *me = &gfa; struct smq_invoke_ctx *ctx = NULL; struct fastrpc_ctx_lst *clst = &fl->clst; struct fastrpc_ioctl_invoke *invoke = &invokefd->inv; Loading Loading @@ -841,6 +847,21 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, hlist_add_head(&ctx->hn, &clst->pending); spin_unlock(&fl->hlock); spin_lock(&me->ctxlock); for (ii = 0; ii < FASTRPC_CTX_MAX; ii++) { if (!me->ctxtable[ii]) { me->ctxtable[ii] = ctx; ctx->ctxid = (ptr_to_uint64(ctx) & ~0xFFF)|(ii << 4); break; } } spin_unlock(&me->ctxlock); VERIFY(err, ii < FASTRPC_CTX_MAX); if (err) { pr_err("adsprpc: out of context memory\n"); goto bail; } *po = ctx; bail: if (ctx && err) Loading @@ -862,6 +883,7 @@ static void context_save_interrupted(struct smq_invoke_ctx *ctx) static void context_free(struct smq_invoke_ctx *ctx) { int i; struct fastrpc_apps *me = &gfa; int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) + REMOTE_SCALARS_OUTBUFS(ctx->sc); spin_lock(&ctx->fl->hlock); Loading @@ -871,6 +893,17 @@ static void context_free(struct smq_invoke_ctx *ctx) fastrpc_mmap_free(ctx->maps[i]); fastrpc_buf_free(ctx->buf, 1); ctx->magic = 0; ctx->ctxid = 0; spin_lock(&me->ctxlock); for (i = 0; i < FASTRPC_CTX_MAX; i++) { if (me->ctxtable[i] == ctx) { me->ctxtable[i] = NULL; break; } } spin_unlock(&me->ctxlock); kfree(ctx); } Loading Loading @@ -1269,7 +1302,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, msg->tid = current->pid; if (kernel) msg->pid = 0; msg->invoke.header.ctx = ptr_to_uint64(ctx); msg->invoke.header.ctx = ctx->ctxid; msg->invoke.header.handle = handle; msg->invoke.header.sc = ctx->sc; msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; Loading @@ -1295,20 +1328,31 @@ static void fastrpc_smd_read_handler(int cid) { struct fastrpc_apps *me = &gfa; struct smq_invoke_rsp rsp = {0}; struct smq_invoke_ctx *ctx; int ret = 0, err = 0; uint32_t index; do { ret = smd_read_from_cb(me->channel[cid].chan, &rsp, sizeof(rsp)); if (ret != sizeof(rsp)) break; ctx = (struct smq_invoke_ctx *)(uint64_to_ptr(rsp.ctx)); VERIFY(err, (ctx && ctx->magic == FASTRPC_CTX_MAGIC)); index = (uint32_t)((rsp.ctx & FASTRPC_CTXID_MASK) >> 4); VERIFY(err, index < FASTRPC_CTX_MAX); if (err) goto bail; context_notify_user(uint64_to_ptr(rsp.ctx), rsp.retval); VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index])); if (err) goto bail; VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp.ctx)) && me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC)); if (err) goto bail; context_notify_user(me->ctxtable[index], rsp.retval); } while (ret == sizeof(rsp)); bail: if (err) pr_err("adsprpc: invalid response or context\n"); Loading Loading @@ -1338,6 +1382,7 @@ static void fastrpc_init(struct fastrpc_apps *me) INIT_HLIST_HEAD(&me->drivers); INIT_HLIST_HEAD(&me->fls); spin_lock_init(&me->hlock); spin_lock_init(&me->ctxlock); mutex_init(&me->smd_mutex); me->channel = &gcinfo[0]; for (i = 0; i < NUM_CHANNELS; i++) { Loading Loading @@ -1870,19 +1915,29 @@ static void fastrpc_glink_notify_rx(void *handle, const void *priv, const void *pkt_priv, const void *ptr, size_t size) { struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr; struct smq_invoke_ctx *ctx; struct fastrpc_apps *me = &gfa; uint32_t index; int err = 0; VERIFY(err, (rsp && size >= sizeof(*rsp))); if (err) goto bail; ctx = (struct smq_invoke_ctx *)(uint64_to_ptr(rsp->ctx)); VERIFY(err, (ctx && ctx->magic == FASTRPC_CTX_MAGIC)); index = (uint32_t)((rsp->ctx & FASTRPC_CTXID_MASK) >> 4); VERIFY(err, index < FASTRPC_CTX_MAX); if (err) goto bail; VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index])); if (err) goto bail; VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp->ctx)) && me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC)); if (err) goto bail; context_notify_user(ctx, rsp->retval); context_notify_user(me->ctxtable[index], rsp->retval); bail: if (err) pr_err("adsprpc: invalid response or context\n"); Loading Loading
drivers/char/adsprpc.c +66 −11 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -66,6 +66,8 @@ #define NUM_CHANNELS 3 /*1 compute 1 cpz 1 mdsp*/ #define NUM_SESSIONS 8 /*8 compute*/ #define FASTRPC_CTX_MAGIC (0xbeeddeed) #define FASTRPC_CTX_MAX (256) #define FASTRPC_CTXID_MASK (0xFF0) #define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0) Loading Loading @@ -155,6 +157,7 @@ struct smq_invoke_ctx { struct overlap **overps; struct smq_msg msg; unsigned int magic; uint64_t ctxid; }; struct fastrpc_ctx_lst { Loading Loading @@ -218,6 +221,8 @@ struct fastrpc_apps { struct device *dev; struct device *modem_cma_dev; bool glink; spinlock_t ctxlock; struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX]; }; struct fastrpc_mmap { Loading Loading @@ -790,7 +795,8 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, struct fastrpc_ioctl_invoke_fd *invokefd, struct smq_invoke_ctx **po) { int err = 0, bufs, size = 0; int err = 0, bufs, ii, size = 0; struct fastrpc_apps *me = &gfa; struct smq_invoke_ctx *ctx = NULL; struct fastrpc_ctx_lst *clst = &fl->clst; struct fastrpc_ioctl_invoke *invoke = &invokefd->inv; Loading Loading @@ -841,6 +847,21 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, hlist_add_head(&ctx->hn, &clst->pending); spin_unlock(&fl->hlock); spin_lock(&me->ctxlock); for (ii = 0; ii < FASTRPC_CTX_MAX; ii++) { if (!me->ctxtable[ii]) { me->ctxtable[ii] = ctx; ctx->ctxid = (ptr_to_uint64(ctx) & ~0xFFF)|(ii << 4); break; } } spin_unlock(&me->ctxlock); VERIFY(err, ii < FASTRPC_CTX_MAX); if (err) { pr_err("adsprpc: out of context memory\n"); goto bail; } *po = ctx; bail: if (ctx && err) Loading @@ -862,6 +883,7 @@ static void context_save_interrupted(struct smq_invoke_ctx *ctx) static void context_free(struct smq_invoke_ctx *ctx) { int i; struct fastrpc_apps *me = &gfa; int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) + REMOTE_SCALARS_OUTBUFS(ctx->sc); spin_lock(&ctx->fl->hlock); Loading @@ -871,6 +893,17 @@ static void context_free(struct smq_invoke_ctx *ctx) fastrpc_mmap_free(ctx->maps[i]); fastrpc_buf_free(ctx->buf, 1); ctx->magic = 0; ctx->ctxid = 0; spin_lock(&me->ctxlock); for (i = 0; i < FASTRPC_CTX_MAX; i++) { if (me->ctxtable[i] == ctx) { me->ctxtable[i] = NULL; break; } } spin_unlock(&me->ctxlock); kfree(ctx); } Loading Loading @@ -1269,7 +1302,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, msg->tid = current->pid; if (kernel) msg->pid = 0; msg->invoke.header.ctx = ptr_to_uint64(ctx); msg->invoke.header.ctx = ctx->ctxid; msg->invoke.header.handle = handle; msg->invoke.header.sc = ctx->sc; msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; Loading @@ -1295,20 +1328,31 @@ static void fastrpc_smd_read_handler(int cid) { struct fastrpc_apps *me = &gfa; struct smq_invoke_rsp rsp = {0}; struct smq_invoke_ctx *ctx; int ret = 0, err = 0; uint32_t index; do { ret = smd_read_from_cb(me->channel[cid].chan, &rsp, sizeof(rsp)); if (ret != sizeof(rsp)) break; ctx = (struct smq_invoke_ctx *)(uint64_to_ptr(rsp.ctx)); VERIFY(err, (ctx && ctx->magic == FASTRPC_CTX_MAGIC)); index = (uint32_t)((rsp.ctx & FASTRPC_CTXID_MASK) >> 4); VERIFY(err, index < FASTRPC_CTX_MAX); if (err) goto bail; context_notify_user(uint64_to_ptr(rsp.ctx), rsp.retval); VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index])); if (err) goto bail; VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp.ctx)) && me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC)); if (err) goto bail; context_notify_user(me->ctxtable[index], rsp.retval); } while (ret == sizeof(rsp)); bail: if (err) pr_err("adsprpc: invalid response or context\n"); Loading Loading @@ -1338,6 +1382,7 @@ static void fastrpc_init(struct fastrpc_apps *me) INIT_HLIST_HEAD(&me->drivers); INIT_HLIST_HEAD(&me->fls); spin_lock_init(&me->hlock); spin_lock_init(&me->ctxlock); mutex_init(&me->smd_mutex); me->channel = &gcinfo[0]; for (i = 0; i < NUM_CHANNELS; i++) { Loading Loading @@ -1870,19 +1915,29 @@ static void fastrpc_glink_notify_rx(void *handle, const void *priv, const void *pkt_priv, const void *ptr, size_t size) { struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr; struct smq_invoke_ctx *ctx; struct fastrpc_apps *me = &gfa; uint32_t index; int err = 0; VERIFY(err, (rsp && size >= sizeof(*rsp))); if (err) goto bail; ctx = (struct smq_invoke_ctx *)(uint64_to_ptr(rsp->ctx)); VERIFY(err, (ctx && ctx->magic == FASTRPC_CTX_MAGIC)); index = (uint32_t)((rsp->ctx & FASTRPC_CTXID_MASK) >> 4); VERIFY(err, index < FASTRPC_CTX_MAX); if (err) goto bail; VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index])); if (err) goto bail; VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp->ctx)) && me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC)); if (err) goto bail; context_notify_user(ctx, rsp->retval); context_notify_user(me->ctxtable[index], rsp->retval); bail: if (err) pr_err("adsprpc: invalid response or context\n"); Loading