msm: adsprpc: maintain local copy of rpra offloaded to DSP

Since DSP is not supposed to modify the base pointer rpra of the
input/output arguments offloaded to DSP, maintain a local copy of
the pointer and use it after receiving interrupt from DSP

Change-Id: I4afade7184cb2aca148060fb0cda06c6174f3b56
Acked-by: Maitreyi Gupta <maitreyi@qti.qualcomm.com>
Signed-off-by: Tharun Kumar Merugu <mtharu@codeaurora.org>
Signed-off-by: Mohammed Nayeem Ur Rahman <mohara@codeaurora.org>
This commit is contained in:
Tharun Kumar Merugu 2019-05-07 00:39:43 +05:30 committed by L R
parent f1fd777147
commit 719a4467ee
1 changed files with 37 additions and 17 deletions

View File

@ -131,9 +131,11 @@ struct smq_invoke_ctx {
int tgid; int tgid;
remote_arg_t *lpra; remote_arg_t *lpra;
remote_arg64_t *rpra; remote_arg64_t *rpra;
remote_arg64_t *lrpra; /* Local copy of rpra for put_args */
int *fds; int *fds;
struct fastrpc_mmap **maps; struct fastrpc_mmap **maps;
struct fastrpc_buf *buf; struct fastrpc_buf *buf;
struct fastrpc_buf *lbuf;
size_t used; size_t used;
struct fastrpc_file *fl; struct fastrpc_file *fl;
uint32_t sc; uint32_t sc;
@ -636,6 +638,7 @@ static void context_free(struct smq_invoke_ctx *ctx)
for (i = 0; i < nbufs; ++i) for (i = 0; i < nbufs; ++i)
fastrpc_mmap_free(ctx->maps[i]); fastrpc_mmap_free(ctx->maps[i]);
fastrpc_buf_free(ctx->buf, 1); fastrpc_buf_free(ctx->buf, 1);
fastrpc_buf_free(ctx->lbuf, 1);
ctx->magic = 0; ctx->magic = 0;
ctx->ctxid = 0; ctx->ctxid = 0;
@ -647,7 +650,6 @@ static void context_free(struct smq_invoke_ctx *ctx)
} }
} }
spin_unlock(&me->ctxlock); spin_unlock(&me->ctxlock);
kfree(ctx); kfree(ctx);
} }
@ -746,7 +748,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va,
static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
{ {
remote_arg64_t *rpra; remote_arg64_t *rpra, *lrpra;
remote_arg_t *lpra = ctx->lpra; remote_arg_t *lpra = ctx->lpra;
struct smq_invoke_buf *list; struct smq_invoke_buf *list;
struct smq_phy_page *pages, *ipage; struct smq_phy_page *pages, *ipage;
@ -755,7 +757,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
int outbufs = REMOTE_SCALARS_OUTBUFS(sc); int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
int bufs = inbufs + outbufs; int bufs = inbufs + outbufs;
uintptr_t args; uintptr_t args;
size_t rlen = 0, copylen = 0, metalen = 0; size_t rlen = 0, copylen = 0, metalen = 0, lrpralen = 0;
int i, inh, oix; int i, inh, oix;
int err = 0; int err = 0;
int mflags = 0; int mflags = 0;
@ -781,7 +783,21 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
ipage += 1; ipage += 1;
} }
metalen = copylen = (size_t)&ipage[0]; metalen = copylen = (size_t)&ipage[0];
/* calculate len requreed for copying */
/* allocate new local rpra buffer */
lrpralen = (size_t)&list[0];
if (lrpralen) {
err = fastrpc_buf_alloc(ctx->fl, lrpralen, &ctx->lbuf);
if (err)
goto bail;
}
if (ctx->lbuf->virt)
memset(ctx->lbuf->virt, 0, lrpralen);
lrpra = ctx->lbuf->virt;
ctx->lrpra = lrpra;
/* calculate len required for copying */
for (oix = 0; oix < inbufs + outbufs; ++oix) { for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix; int i = ctx->overps[oix]->raix;
uintptr_t mstart, mend; uintptr_t mstart, mend;
@ -829,13 +845,13 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
ipage++; ipage++;
} }
/* map ion buffers */ /* map ion buffers */
for (i = 0; i < inbufs + outbufs; ++i) { for (i = 0; rpra && lrpra && i < inbufs + outbufs; ++i) {
struct fastrpc_mmap *map = ctx->maps[i]; struct fastrpc_mmap *map = ctx->maps[i];
uint64_t buf = ptr_to_uint64(lpra[i].buf.pv); uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
size_t len = lpra[i].buf.len; size_t len = lpra[i].buf.len;
rpra[i].buf.pv = 0; rpra[i].buf.pv = lrpra[i].buf.pv = 0;
rpra[i].buf.len = len; rpra[i].buf.len = lrpra[i].buf.len = len;
if (!len) if (!len)
continue; continue;
if (map) { if (map) {
@ -854,11 +870,11 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
pages[idx].addr |= STREAM_ID; pages[idx].addr |= STREAM_ID;
pages[idx].size = num << PAGE_SHIFT; pages[idx].size = num << PAGE_SHIFT;
} }
rpra[i].buf.pv = buf; rpra[i].buf.pv = lrpra[i].buf.pv = buf;
} }
/* copy non ion buffers */ /* copy non ion buffers */
rlen = copylen - metalen; rlen = copylen - metalen;
for (oix = 0; oix < inbufs + outbufs; ++oix) { for (oix = 0; rpra && lrpra && oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix; int i = ctx->overps[oix]->raix;
struct fastrpc_mmap *map = ctx->maps[i]; struct fastrpc_mmap *map = ctx->maps[i];
size_t mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart; size_t mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
@ -875,7 +891,8 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
VERIFY(err, rlen >= mlen); VERIFY(err, rlen >= mlen);
if (err) if (err)
goto bail; goto bail;
rpra[i].buf.pv = (args - ctx->overps[oix]->offset); rpra[i].buf.pv = lrpra[i].buf.pv =
(args - ctx->overps[oix]->offset);
pages[list[i].pgidx].addr = ctx->buf->phys - pages[list[i].pgidx].addr = ctx->buf->phys -
ctx->overps[oix]->offset + ctx->overps[oix]->offset +
(copylen - rlen); (copylen - rlen);
@ -896,15 +913,18 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
} }
for (i = 0; i < inbufs; ++i) { for (i = 0; i < inbufs; ++i) {
if (rpra[i].buf.len) if (rpra && lrpra && rpra[i].buf.len)
dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv), dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv),
uint64_to_ptr(rpra[i].buf.pv + rpra[i].buf.len)); uint64_to_ptr(rpra[i].buf.pv + rpra[i].buf.len));
} }
inh = inbufs + outbufs; inh = inbufs + outbufs;
for (i = 0; i < REMOTE_SCALARS_INHANDLES(sc); i++) { for (i = 0; rpra && lrpra && i < REMOTE_SCALARS_INHANDLES(sc); i++) {
rpra[inh + i].buf.pv = ptr_to_uint64(ctx->lpra[inh + i].buf.pv); rpra[inh + i].buf.pv = lrpra[inh + i].buf.pv =
rpra[inh + i].buf.len = ctx->lpra[inh + i].buf.len; ptr_to_uint64(ctx->lpra[inh + i].buf.pv);
rpra[inh + i].h = ctx->lpra[inh + i].h; rpra[inh + i].buf.len = lrpra[inh + i].buf.len =
ctx->lpra[inh + i].buf.len;
rpra[inh + i].h = lrpra[inh + i].h =
ctx->lpra[inh + i].h;
} }
dmac_flush_range((char *)rpra, (char *)rpra + ctx->used); dmac_flush_range((char *)rpra, (char *)rpra + ctx->used);
bail: bail:
@ -915,7 +935,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
remote_arg_t *upra) remote_arg_t *upra)
{ {
uint32_t sc = ctx->sc; uint32_t sc = ctx->sc;
remote_arg64_t *rpra = ctx->rpra; remote_arg64_t *rpra = ctx->lrpra;
int i, inbufs, outbufs, outh, num; int i, inbufs, outbufs, outh, num;
int err = 0; int err = 0;
@ -974,7 +994,7 @@ static void inv_args(struct smq_invoke_ctx* ctx)
{ {
int i, inbufs, outbufs; int i, inbufs, outbufs;
uint32_t sc = ctx->sc; uint32_t sc = ctx->sc;
remote_arg64_t *rpra = ctx->rpra; remote_arg64_t *rpra = ctx->lrpra;
int used = ctx->used; int used = ctx->used;
int inv = 0; int inv = 0;