Commit 8b5b4562 authored by Ling Xu's avatar Ling Xu Committed by Greg Kroah-Hartman
Browse files

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: c68cfb71 ("misc: fastrpc: Add support for context Invoke method")
Cc: stable@kernel.org
Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Co-developed-by: default avatarEkansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: default avatarEkansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: default avatarLing Xu <quic_lxu5@quicinc.com>
Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: default avatarSrinivas Kandagatla <srini@kernel.org>
Link: https://lore.kernel.org/r/20250912131236.303102-2-srini@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 810b7900
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -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;
	}