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: 35a82b87135d ("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>
---
drivers/misc/fastrpc.c | 44 ++++++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 17 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index d950a179bff8..3b7ad4a043eb 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -363,7 +363,7 @@ static int fastrpc_map_get(struct fastrpc_map *map)
static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
- struct fastrpc_map **ppmap, bool take_ref)
+ struct fastrpc_map **ppmap)
{
struct fastrpc_session_ctx *sess = fl->sctx;
struct fastrpc_map *map = NULL;
@@ -379,15 +379,6 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
if (map->fd != fd || map->buf != buf)
continue;
- if (take_ref) {
- ret = fastrpc_map_get(map);
- if (ret) {
- dev_dbg(sess->dev, "%s: Failed to get map fd=%d ret=%d\n",
- __func__, fd, ret);
- break;
- }
- }
-
*ppmap = map;
ret = 0;
break;
@@ -757,7 +748,7 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = {
.release = fastrpc_release,
};
-static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
+static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
u64 len, u32 attr, struct fastrpc_map **ppmap)
{
struct fastrpc_session_ctx *sess = fl->sctx;
@@ -766,9 +757,6 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
struct scatterlist *sgl = NULL;
int err = 0, sgl_index = 0;
- if (!fastrpc_map_lookup(fl, fd, ppmap, true))
- return 0;
-
map = kzalloc(sizeof(*map), GFP_KERNEL);
if (!map)
return -ENOMEM;
@@ -853,6 +841,24 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
return err;
}
+static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
+ u64 len, u32 attr, struct fastrpc_map **ppmap)
+{
+ struct fastrpc_session_ctx *sess = fl->sctx;
+ int err = 0;
+
+ if (!fastrpc_map_lookup(fl, fd, ppmap)) {
+ if (!fastrpc_map_get(*ppmap))
+ return 0;
+ dev_dbg(sess->dev, "%s: Failed to get map fd=%d\n",
+ __func__, fd);
+ }
+
+ err = fastrpc_map_attach(fl, fd, len, attr, ppmap);
+
+ return err;
+}
+
/*
* Fastrpc payload buffer with metadata looks like:
*
@@ -925,8 +931,12 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
ctx->args[i].length == 0)
continue;
- err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
- ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
+ if (i < ctx->nbufs)
+ err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
+ ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
+ else
+ err = fastrpc_map_attach(ctx->fl, ctx->args[i].fd,
+ ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
if (err) {
dev_err(dev, "Error Creating map %d\n", err);
return -EINVAL;
@@ -1116,7 +1126,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
for (i = 0; i < FASTRPC_MAX_FDLIST; i++) {
if (!fdlist[i])
break;
- if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false))
+ if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap))
fastrpc_map_put(mmap);
}
--
2.34.1
Hi Ling, kernel test robot noticed the following build warnings: [auto build test WARNING on char-misc/char-misc-testing] [also build test WARNING on char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.16 next-20250806] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ling-Xu/misc-fastrpc-Save-actual-DMA-size-in-fastrpc_map-structure/20250806-200133 base: char-misc/char-misc-testing patch link: https://lore.kernel.org/r/20250806115114.688814-5-quic_lxu5%40quicinc.com patch subject: [PATCH v2 4/4] misc: fastrpc: Skip reference for DMA handles config: hexagon-randconfig-002-20250807 (https://download.01.org/0day-ci/archive/20250807/202508070731.S30957lV-lkp@intel.com/config) compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 7b8dea265e72c3037b6b1e54d5ab51b7e14f328b) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250807/202508070731.S30957lV-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202508070731.S30957lV-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/misc/fastrpc.c:368:30: warning: unused variable 'sess' [-Wunused-variable] 368 | struct fastrpc_session_ctx *sess = fl->sctx; | ^~~~ 1 warning generated. vim +/sess +368 drivers/misc/fastrpc.c c68cfb718c8f97 Srinivas Kandagatla 2019-02-08 363 8f6c1d8c4f0cc3 Vamsi Krishna Gattupalli 2022-02-14 364 8f6c1d8c4f0cc3 Vamsi Krishna Gattupalli 2022-02-14 365 static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, 1922c68c56c660 Ling Xu 2025-08-06 366 struct fastrpc_map **ppmap) c68cfb718c8f97 Srinivas Kandagatla 2019-02-08 367 { 9446fa1683a7e3 Abel Vesa 2022-11-24 @368 struct fastrpc_session_ctx *sess = fl->sctx; c68cfb718c8f97 Srinivas Kandagatla 2019-02-08 369 struct fastrpc_map *map = NULL; d259063578ed76 Ling Xu 2025-08-06 370 struct dma_buf *buf; 9446fa1683a7e3 Abel Vesa 2022-11-24 371 int ret = -ENOENT; c68cfb718c8f97 Srinivas Kandagatla 2019-02-08 372 d259063578ed76 Ling Xu 2025-08-06 373 buf = dma_buf_get(fd); d259063578ed76 Ling Xu 2025-08-06 374 if (IS_ERR(buf)) d259063578ed76 Ling Xu 2025-08-06 375 return PTR_ERR(buf); d259063578ed76 Ling Xu 2025-08-06 376 9446fa1683a7e3 Abel Vesa 2022-11-24 377 spin_lock(&fl->lock); c68cfb718c8f97 Srinivas Kandagatla 2019-02-08 378 list_for_each_entry(map, &fl->maps, node) { d259063578ed76 Ling Xu 2025-08-06 379 if (map->fd != fd || map->buf != buf) 9446fa1683a7e3 Abel Vesa 2022-11-24 380 continue; 9446fa1683a7e3 Abel Vesa 2022-11-24 381 9446fa1683a7e3 Abel Vesa 2022-11-24 382 *ppmap = map; 9446fa1683a7e3 Abel Vesa 2022-11-24 383 ret = 0; 9446fa1683a7e3 Abel Vesa 2022-11-24 384 break; c68cfb718c8f97 Srinivas Kandagatla 2019-02-08 385 } 9446fa1683a7e3 Abel Vesa 2022-11-24 386 spin_unlock(&fl->lock); 8f6c1d8c4f0cc3 Vamsi Krishna Gattupalli 2022-02-14 387 8f6c1d8c4f0cc3 Vamsi Krishna Gattupalli 2022-02-14 388 return ret; 8f6c1d8c4f0cc3 Vamsi Krishna Gattupalli 2022-02-14 389 } 8f6c1d8c4f0cc3 Vamsi Krishna Gattupalli 2022-02-14 390 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
© 2016 - 2025 Red Hat, Inc.