Skip to content

Commit 10df039

Browse files
quic-lxu5gregkh
authored andcommitted
misc: fastrpc: Skip reference for DMA handles
If multiple dma handles are passed with same fd over a remote call the kernel driver takes a reference and expects that put for the map will be called as many times to free the map. But DSP only updates the fd one time in the fd list when the DSP refcount goes to zero and hence kernel make put call only once for the fd. This can cause SMMU fault issue as the same fd can be used in future for some other call. Fixes: 35a82b8 ("misc: fastrpc: Add dma handle implementation") Cc: stable@kernel.org Co-developed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com> Signed-off-by: Ling Xu <quic_lxu5@quicinc.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Srinivas Kandagatla <srini@kernel.org> Link: https://lore.kernel.org/r/20250912131236.303102-5-srini@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent da1ba64 commit 10df039

1 file changed

Lines changed: 27 additions & 18 deletions

File tree

drivers/misc/fastrpc.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,8 @@ static int fastrpc_map_get(struct fastrpc_map *map)
363363

364364

365365
static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
366-
struct fastrpc_map **ppmap, bool take_ref)
366+
struct fastrpc_map **ppmap)
367367
{
368-
struct fastrpc_session_ctx *sess = fl->sctx;
369368
struct fastrpc_map *map = NULL;
370369
struct dma_buf *buf;
371370
int ret = -ENOENT;
@@ -379,15 +378,6 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
379378
if (map->fd != fd || map->buf != buf)
380379
continue;
381380

382-
if (take_ref) {
383-
ret = fastrpc_map_get(map);
384-
if (ret) {
385-
dev_dbg(sess->dev, "%s: Failed to get map fd=%d ret=%d\n",
386-
__func__, fd, ret);
387-
break;
388-
}
389-
}
390-
391381
*ppmap = map;
392382
ret = 0;
393383
break;
@@ -757,7 +747,7 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = {
757747
.release = fastrpc_release,
758748
};
759749

760-
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
750+
static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
761751
u64 len, u32 attr, struct fastrpc_map **ppmap)
762752
{
763753
struct fastrpc_session_ctx *sess = fl->sctx;
@@ -766,9 +756,6 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
766756
struct scatterlist *sgl = NULL;
767757
int err = 0, sgl_index = 0;
768758

769-
if (!fastrpc_map_lookup(fl, fd, ppmap, true))
770-
return 0;
771-
772759
map = kzalloc(sizeof(*map), GFP_KERNEL);
773760
if (!map)
774761
return -ENOMEM;
@@ -853,6 +840,24 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
853840
return err;
854841
}
855842

843+
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
844+
u64 len, u32 attr, struct fastrpc_map **ppmap)
845+
{
846+
struct fastrpc_session_ctx *sess = fl->sctx;
847+
int err = 0;
848+
849+
if (!fastrpc_map_lookup(fl, fd, ppmap)) {
850+
if (!fastrpc_map_get(*ppmap))
851+
return 0;
852+
dev_dbg(sess->dev, "%s: Failed to get map fd=%d\n",
853+
__func__, fd);
854+
}
855+
856+
err = fastrpc_map_attach(fl, fd, len, attr, ppmap);
857+
858+
return err;
859+
}
860+
856861
/*
857862
* Fastrpc payload buffer with metadata looks like:
858863
*
@@ -925,8 +930,12 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
925930
ctx->args[i].length == 0)
926931
continue;
927932

928-
err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
929-
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
933+
if (i < ctx->nbufs)
934+
err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
935+
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
936+
else
937+
err = fastrpc_map_attach(ctx->fl, ctx->args[i].fd,
938+
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
930939
if (err) {
931940
dev_err(dev, "Error Creating map %d\n", err);
932941
return -EINVAL;
@@ -1116,7 +1125,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
11161125
for (i = 0; i < FASTRPC_MAX_FDLIST; i++) {
11171126
if (!fdlist[i])
11181127
break;
1119-
if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false))
1128+
if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap))
11201129
fastrpc_map_put(mmap);
11211130
}
11221131

0 commit comments

Comments
 (0)