[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250806115114.688814-2-quic_lxu5@quicinc.com>
Date: Wed, 6 Aug 2025 17:21:11 +0530
From: Ling Xu <quic_lxu5@...cinc.com>
To: <srini@...nel.org>, <amahesh@....qualcomm.com>, <arnd@...db.de>,
<gregkh@...uxfoundation.org>, <sumit.semwal@...aro.org>,
<christian.koenig@....com>, <thierry.escande@...aro.org>,
<quic_vgattupa@...cinc.com>
CC: <quic_kuiw@...cinc.com>, <ekansh.gupta@....qualcomm.com>,
<dri-devel@...ts.freedesktop.org>, <linux-arm-msm@...r.kernel.org>,
<linux-media@...r.kernel.org>, <linaro-mm-sig@...ts.linaro.org>,
<linux-kernel@...r.kernel.org>, Ling Xu <quic_lxu5@...cinc.com>,
<stable@...nel.org>,
Dmitry Baryshkov <dmitry.baryshkov@....qualcomm.com>
Subject: [PATCH v2 1/4] misc: fastrpc: Save actual DMA size in fastrpc_map structure
For user passed fd buffer, map is created using DMA calls. The
map related information is stored in fastrpc_map structure. The
actual DMA size is not stored in the structure. Store the actual
size of buffer and check it against the user passed size.
Fixes: c68cfb718c8f ("misc: fastrpc: Add support for context Invoke method")
Cc: stable@...nel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@....qualcomm.com>
Co-developed-by: Ekansh Gupta <ekansh.gupta@....qualcomm.com>
Signed-off-by: Ekansh Gupta <ekansh.gupta@....qualcomm.com>
Signed-off-by: Ling Xu <quic_lxu5@...cinc.com>
---
drivers/misc/fastrpc.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 53e88a1bc430..52571916acd4 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -323,11 +323,11 @@ static void fastrpc_free_map(struct kref *ref)
perm.vmid = QCOM_SCM_VMID_HLOS;
perm.perm = QCOM_SCM_PERM_RWX;
- err = qcom_scm_assign_mem(map->phys, map->size,
+ err = qcom_scm_assign_mem(map->phys, map->len,
&src_perms, &perm, 1);
if (err) {
dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
- map->phys, map->size, err);
+ map->phys, map->len, err);
return;
}
}
@@ -758,7 +758,8 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
struct fastrpc_session_ctx *sess = fl->sctx;
struct fastrpc_map *map = NULL;
struct sg_table *table;
- int err = 0;
+ struct scatterlist *sgl = NULL;
+ int err = 0, sgl_index = 0;
if (!fastrpc_map_lookup(fl, fd, ppmap, true))
return 0;
@@ -798,7 +799,15 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
map->phys = sg_dma_address(map->table->sgl);
map->phys += ((u64)fl->sctx->sid << 32);
}
- map->size = len;
+ for_each_sg(map->table->sgl, sgl, map->table->nents,
+ sgl_index)
+ map->size += sg_dma_len(sgl);
+ if (len > map->size) {
+ dev_dbg(sess->dev, "Bad size passed len 0x%llx map size 0x%llx\n",
+ len, map->size);
+ err = -EINVAL;
+ goto map_err;
+ }
map->va = sg_virt(map->table->sgl);
map->len = len;
@@ -815,10 +824,10 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
dst_perms[1].vmid = fl->cctx->vmperms[0].vmid;
dst_perms[1].perm = QCOM_SCM_PERM_RWX;
map->attr = attr;
- err = qcom_scm_assign_mem(map->phys, (u64)map->size, &src_perms, dst_perms, 2);
+ err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2);
if (err) {
dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n",
- map->phys, map->size, err);
+ map->phys, map->len, err);
goto map_err;
}
}
@@ -2046,7 +2055,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
args[0].length = sizeof(req_msg);
pages.addr = map->phys;
- pages.size = map->size;
+ pages.size = map->len;
args[1].ptr = (u64) (uintptr_t) &pages;
args[1].length = sizeof(pages);
@@ -2061,7 +2070,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]);
if (err) {
dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n",
- req.fd, req.vaddrin, map->size);
+ req.fd, req.vaddrin, map->len);
goto err_invoke;
}
@@ -2074,7 +2083,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
/* unmap the memory and release the buffer */
req_unmap.vaddr = (uintptr_t) rsp_msg.vaddr;
- req_unmap.length = map->size;
+ req_unmap.length = map->len;
fastrpc_req_mem_unmap_impl(fl, &req_unmap);
return -EFAULT;
}
--
2.34.1
Powered by blists - more mailing lists