* [PATCH v1] misc: fastrpc: avoid duplicate DMA mappings in fastrpc_create_maps()
@ 2026-06-25 8:08 Jianping Li
2026-07-03 5:16 ` Ekansh Gupta
0 siblings, 1 reply; 3+ messages in thread
From: Jianping Li @ 2026-06-25 8:08 UTC (permalink / raw)
To: Srinivas Kandagatla, Amol Maheshwari
Cc: Jianping Li, Arnd Bergmann, Greg Kroah-Hartman, Dmitry Baryshkov,
Ling Xu, Ekansh Gupta, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, stable
fastrpc_create_maps() performs map lookup only for buffer
arguments (i < ctx->nbufs) via fastrpc_map_create(). For
arguments beyond this range, no lookup is performed, which
can result in duplicate DMA mappings for the same file
descriptor.
Additionally, if the same file descriptor is passed multiple
times within a single invocation, performing lookups with
reference counting would increment the reference multiple
times, while fastrpc_put_args() would release it only once,
leading to an imbalanced reference count.
Fix this by allowing fastrpc_map_create() to control whether
the lookup should take a reference. For arguments beyond
ctx->nbufs, the lookup is performed without taking a
reference, ensuring that existing mappings are reused
without introducing duplicate DMA mappings or reference
count imbalance.
Fixes: 10df039834f84 ("misc: fastrpc: Skip reference for DMA handles")
Cc: stable@kernel.org
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
---
drivers/misc/fastrpc.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index a9b2ae44c06f..2622a1360a65 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -924,9 +924,9 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
}
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
- u64 len, u32 attr, struct fastrpc_map **ppmap)
+ u64 len, u32 attr, struct fastrpc_map **ppmap, bool take_ref)
{
- if (!fastrpc_map_lookup(fl, fd, ppmap, true))
+ if (!fastrpc_map_lookup(fl, fd, ppmap, take_ref))
return 0;
return fastrpc_map_attach(fl, fd, len, attr, ppmap);
@@ -999,23 +999,23 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
int i, err;
for (i = 0; i < ctx->nscalars; ++i) {
+ bool take_ref = true;
if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1 ||
ctx->args[i].length == 0)
continue;
- 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 (i >= ctx->nbufs)
+ take_ref = false;
+
+ err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, ctx->args[i].length,
+ ctx->args[i].attr, &ctx->maps[i], take_ref);
if (err) {
dev_err(dev, "Error Creating map %d\n", err);
return -EINVAL;
}
-
}
+
return 0;
}
@@ -1508,7 +1508,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
fl->pd = USER_PD;
if (init.filelen && init.filefd) {
- err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map);
+ err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map, true);
if (err)
goto err;
}
@@ -2100,7 +2100,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
return -EFAULT;
/* create SMMU mapping */
- err = fastrpc_map_create(fl, req.fd, req.length, 0, &map);
+ err = fastrpc_map_create(fl, req.fd, req.length, 0, &map, true);
if (err) {
dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
return err;
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v1] misc: fastrpc: avoid duplicate DMA mappings in fastrpc_create_maps()
2026-06-25 8:08 [PATCH v1] misc: fastrpc: avoid duplicate DMA mappings in fastrpc_create_maps() Jianping Li
@ 2026-07-03 5:16 ` Ekansh Gupta
2026-07-03 6:28 ` Jianping Li
0 siblings, 1 reply; 3+ messages in thread
From: Ekansh Gupta @ 2026-07-03 5:16 UTC (permalink / raw)
To: Jianping Li, Srinivas Kandagatla, Amol Maheshwari
Cc: Arnd Bergmann, Greg Kroah-Hartman, Dmitry Baryshkov, Ling Xu,
linux-arm-msm, dri-devel, linux-kernel, quic_chennak, stable
On 25-06-2026 13:38, Jianping Li wrote:
> fastrpc_create_maps() performs map lookup only for buffer
> arguments (i < ctx->nbufs) via fastrpc_map_create(). For
> arguments beyond this range, no lookup is performed, which
> can result in duplicate DMA mappings for the same file
> descriptor.
>
> Additionally, if the same file descriptor is passed multiple
> times within a single invocation, performing lookups with
> reference counting would increment the reference multiple
> times, while fastrpc_put_args() would release it only once,
> leading to an imbalanced reference count.
>
> Fix this by allowing fastrpc_map_create() to control whether
> the lookup should take a reference. For arguments beyond
> ctx->nbufs, the lookup is performed without taking a
> reference, ensuring that existing mappings are reused
> without introducing duplicate DMA mappings or reference
> count imbalance.
>
> Fixes: 10df039834f84 ("misc: fastrpc: Skip reference for DMA handles")
> Cc: stable@kernel.org
> Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
> ---
> drivers/misc/fastrpc.c | 22 +++++++++++-----------
> 1 file changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index a9b2ae44c06f..2622a1360a65 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
> @@ -924,9 +924,9 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
> }
>
> static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
> - u64 len, u32 attr, struct fastrpc_map **ppmap)
> + u64 len, u32 attr, struct fastrpc_map **ppmap, bool take_ref)
> {
> - if (!fastrpc_map_lookup(fl, fd, ppmap, true))
> + if (!fastrpc_map_lookup(fl, fd, ppmap, take_ref))
> return 0;
>
> return fastrpc_map_attach(fl, fd, len, attr, ppmap);
> @@ -999,23 +999,23 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
> int i, err;
>
> for (i = 0; i < ctx->nscalars; ++i) {
> + bool take_ref = true;
bool take_ref = i < ctx->nbufs, also add a comment stating why reference
should be skipped for DMA handles.>
> if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1 ||
> ctx->args[i].length == 0)
> continue;
>
> - 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 (i >= ctx->nbufs)
> + take_ref = false;
> +
> + err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, ctx->args[i].length,
> + ctx->args[i].attr, &ctx->maps[i], take_ref);
> if (err) {
> dev_err(dev, "Error Creating map %d\n", err);
> return -EINVAL;
> }
> -
> }
> +
> return 0;
> }
>
> @@ -1508,7 +1508,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
> fl->pd = USER_PD;
>
> if (init.filelen && init.filefd) {
> - err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map);
> + err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map, true);
> if (err)
> goto err;
> }
> @@ -2100,7 +2100,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
> return -EFAULT;
>
> /* create SMMU mapping */
> - err = fastrpc_map_create(fl, req.fd, req.length, 0, &map);
> + err = fastrpc_map_create(fl, req.fd, req.length, 0, &map, true);
> if (err) {
> dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
> return err;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v1] misc: fastrpc: avoid duplicate DMA mappings in fastrpc_create_maps()
2026-07-03 5:16 ` Ekansh Gupta
@ 2026-07-03 6:28 ` Jianping Li
0 siblings, 0 replies; 3+ messages in thread
From: Jianping Li @ 2026-07-03 6:28 UTC (permalink / raw)
To: Ekansh Gupta, Srinivas Kandagatla, amahesh
Cc: arnd, Greg KH, Dmitry Baryshkov, quic_lxu5, linux-arm-msm,
dri-devel, linux-kernel, quic_chennak, stable
On 7/3/2026 1:16 PM, Ekansh Gupta wrote:
> On 25-06-2026 13:38, Jianping Li wrote:
>> fastrpc_create_maps() performs map lookup only for buffer
>> arguments (i < ctx->nbufs) via fastrpc_map_create(). For
>> arguments beyond this range, no lookup is performed, which
>> can result in duplicate DMA mappings for the same file
>> descriptor.
>>
>> Additionally, if the same file descriptor is passed multiple
>> times within a single invocation, performing lookups with
>> reference counting would increment the reference multiple
>> times, while fastrpc_put_args() would release it only once,
>> leading to an imbalanced reference count.
>>
>> Fix this by allowing fastrpc_map_create() to control whether
>> the lookup should take a reference. For arguments beyond
>> ctx->nbufs, the lookup is performed without taking a
>> reference, ensuring that existing mappings are reused
>> without introducing duplicate DMA mappings or reference
>> count imbalance.
>>
>> Fixes: 10df039834f84 ("misc: fastrpc: Skip reference for DMA handles")
>> Cc: stable@kernel.org
>> Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
>> ---
>> drivers/misc/fastrpc.c | 22 +++++++++++-----------
>> 1 file changed, 11 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
>> index a9b2ae44c06f..2622a1360a65 100644
>> --- a/drivers/misc/fastrpc.c
>> +++ b/drivers/misc/fastrpc.c
>> @@ -924,9 +924,9 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
>> }
>>
>> static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
>> - u64 len, u32 attr, struct fastrpc_map **ppmap)
>> + u64 len, u32 attr, struct fastrpc_map **ppmap, bool take_ref)
>> {
>> - if (!fastrpc_map_lookup(fl, fd, ppmap, true))
>> + if (!fastrpc_map_lookup(fl, fd, ppmap, take_ref))
>> return 0;
>>
>> return fastrpc_map_attach(fl, fd, len, attr, ppmap);
>> @@ -999,23 +999,23 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
>> int i, err;
>>
>> for (i = 0; i < ctx->nscalars; ++i) {
>> + bool take_ref = true;
> bool take_ref = i < ctx->nbufs, also add a comment stating why reference
> should be skipped for DMA handles.>
Thanks for the review.
That's a good point. I'll initialize the variable as:
bool take_ref = i < ctx->nbufs;
and add a comment explaining that DMA handle arguments can reuse an
existing mapping and should not take an additional reference, otherwise
multiple references may be acquired for the same fd while only a single
release is performed during cleanup.
>> if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1 ||
>> ctx->args[i].length == 0)
>> continue;
>>
>> - 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 (i >= ctx->nbufs)
>> + take_ref = false;
>> +
>> + err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, ctx->args[i].length,
>> + ctx->args[i].attr, &ctx->maps[i], take_ref);
>> if (err) {
>> dev_err(dev, "Error Creating map %d\n", err);
>> return -EINVAL;
>> }
>> -
>> }
>> +
>> return 0;
>> }
>>
>> @@ -1508,7 +1508,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
>> fl->pd = USER_PD;
>>
>> if (init.filelen && init.filefd) {
>> - err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map);
>> + err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map, true);
>> if (err)
>> goto err;
>> }
>> @@ -2100,7 +2100,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
>> return -EFAULT;
>>
>> /* create SMMU mapping */
>> - err = fastrpc_map_create(fl, req.fd, req.length, 0, &map);
>> + err = fastrpc_map_create(fl, req.fd, req.length, 0, &map, true);
>> if (err) {
>> dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
>> return err;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-03 6:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-25 8:08 [PATCH v1] misc: fastrpc: avoid duplicate DMA mappings in fastrpc_create_maps() Jianping Li
2026-07-03 5:16 ` Ekansh Gupta
2026-07-03 6:28 ` Jianping Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox