msm: ADSPRPC: Use ID in response to get context pointer

Send context ID in rpc header instead of context pointer.
Validate context ID received in response and get context pointer.

Change-Id: I9cfd10d0c1b25c3085b8e15c7ca1c8ff214bf10d
Acked-by: Viswanatham Paduchuri <vpaduchu@qti.qualcomm.com>
Signed-off-by: Tharun Kumar Merugu <mtharu@codeaurora.org>
This commit is contained in:
Tharun Kumar Merugu 2018-02-08 15:30:54 +05:30 committed by syphyr
parent 489099a755
commit fb3ab18a56

View file

@ -55,6 +55,8 @@
#define BALIGN 32
#define NUM_CHANNELS 1 /*8 compute 2 cpz 1 modem*/
#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)
@ -136,6 +138,7 @@ struct smq_invoke_ctx {
struct overlap *overs;
struct overlap **overps;
unsigned int magic;
uint64_t ctxid;
};
struct fastrpc_ctx_lst {
@ -174,6 +177,8 @@ struct fastrpc_apps {
spinlock_t hlock;
int32_t domain_id;
struct device *adsp_mem_device;
spinlock_t ctxlock;
struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX];
};
struct fastrpc_mmap {
@ -530,7 +535,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;
@ -582,6 +588,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)
@ -603,6 +624,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);
@ -612,6 +634,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);
}
@ -978,7 +1011,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;
@ -1015,20 +1048,31 @@ static void fastrpc_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 & ~1)) &&
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");
@ -1058,6 +1102,7 @@ static void fastrpc_init(struct fastrpc_apps *me)
INIT_HLIST_HEAD(&me->drivers);
INIT_HLIST_HEAD(&me->maps);
spin_lock_init(&me->hlock);
spin_lock_init(&me->ctxlock);
mutex_init(&me->smd_mutex);
for (i = 0; i < NUM_CHANNELS; i++)
init_completion(&me->channel[i].work);