mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
misc: fastrpc: Save actual DMA size in fastrpc_map structure
[ Upstream commit 8b5b456222fd604079b5cf2af1f25ad690f54a25 ]
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: c68cfb718c ("misc: fastrpc: Add support for context Invoke method")
Cc: stable@kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
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@linaro.org>
Signed-off-by: Srinivas Kandagatla <srini@kernel.org>
Link: https://lore.kernel.org/r/20250912131236.303102-2-srini@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
78e5fa79ed
commit
0fa2185104
@@ -322,11 +322,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;
|
||||
}
|
||||
}
|
||||
@@ -752,7 +752,8 @@ static int fastrpc_map_attach(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;
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map)
|
||||
@@ -789,7 +790,15 @@ static int fastrpc_map_attach(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;
|
||||
|
||||
@@ -806,10 +815,10 @@ static int fastrpc_map_attach(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;
|
||||
}
|
||||
}
|
||||
@@ -2063,7 +2072,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);
|
||||
@@ -2078,7 +2087,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;
|
||||
}
|
||||
|
||||
@@ -2091,7 +2100,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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user