Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc64d0e6 authored by Mitchel Humpherys's avatar Mitchel Humpherys
Browse files

msm: ADSPRPC: Fix offset for input and output buffers



The buffers being passed to remote processor did not have
the right offset into the IOMMU VA for cases where the offset
was greater than 4K.

Change-Id: I32360a337ecbb9ebe3d33e5a6d680b1033945641
Acked-by: default avatarSathish Ambley <sambley@qti.qualcomm.com>
Signed-off-by: default avatarMitchel Humpherys <mitchelh@codeaurora.org>
parent 8e5d905c
Loading
Loading
Loading
Loading
+45 −23
Original line number Diff line number Diff line
@@ -496,11 +496,15 @@ static void context_list_dtor(struct fastrpc_apps *me,
	spin_unlock(&clst->hlock);
}

static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
		struct fastrpc_buf *ibuf, struct fastrpc_buf *obuf, int cid)
static int get_page_list(uint32_t kernel, struct smq_invoke_ctx *ctx, int cid)
{
	struct fastrpc_apps *me = &gfa;
	struct smq_phy_page *pgstart, *pages;
	struct smq_invoke_buf *list;
	struct fastrpc_buf *ibuf = &ctx->dev->buf;
	struct fastrpc_buf *obuf = &ctx->obuf;
	remote_arg_t *pra = ctx->pra;
	uint32_t sc = ctx->sc;
	int i, rlen, err = 0;
	int inbufs = REMOTE_SCALARS_INBUFS(sc);
	int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
@@ -536,11 +540,21 @@ static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
			continue;
		buf = pra[i].buf.pv;
		num = buf_num_pages(buf, len);
		if (!kernel)
		if (!kernel) {
			if (me->channel[cid].smmu.enabled) {
				VERIFY(err, 0 != access_ok(i >= inbufs ?
					VERIFY_WRITE : VERIFY_READ,
					(void __user *)buf, len));
				if (err)
					goto bail;
				if (ctx->fds && (ctx->fds[i] >= 0))
					list[i].num = 1;
			} else {
				list[i].num = buf_get_pages(buf, len, num,
				i >= inbufs, pages, rlen / sizeof(*pages));
		else
			list[i].num = 0;
						i >= inbufs, pages,
						rlen / sizeof(*pages));
			}
		}
		VERIFY(err, list[i].num >= 0);
		if (err)
			goto bail;
@@ -569,20 +583,23 @@ static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
	return err;
}

static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
			remote_arg_t *rpra, remote_arg_t *upra,
			struct fastrpc_buf *ibuf, struct fastrpc_buf **abufs,
			int *nbufs, int *fds, struct ion_handle **handles,
			int cid)
static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
			remote_arg_t *upra, int cid)
{
	struct fastrpc_apps *me = &gfa;
	struct smq_invoke_buf *list;
	struct fastrpc_buf *pbuf = ibuf, *obufs = 0;
	struct fastrpc_buf *pbuf = &ctx->obuf, *obufs = 0;
	struct smq_phy_page *pages;
	struct vm_area_struct *vma;
	struct ion_handle **handles = ctx->handles;
	void *args;
	remote_arg_t *pra = ctx->pra;
	remote_arg_t *rpra = ctx->rpra;
	uint32_t sc = ctx->sc, start;
	int i, rlen, size, used, inh, bufs = 0, err = 0;
	int inbufs = REMOTE_SCALARS_INBUFS(sc);
	int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
	int *fds = ctx->fds, idx, num;
	unsigned long len;
	ion_phys_addr_t iova;

@@ -598,7 +615,10 @@ static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
			continue;
		if (me->channel[cid].smmu.enabled &&
					fds && (fds[i] >= 0)) {
			start = buf_page_start(pra[i].buf.pv);
			len = buf_page_size(pra[i].buf.len);
			num = buf_num_pages(pra[i].buf.pv, pra[i].buf.len);
			idx = list[i].pgidx;
			handles[i] = ion_import_dma_buf(me->iclient, fds[i]);
			VERIFY(err, 0 == IS_ERR_OR_NULL(handles[i]));
			if (err)
@@ -606,12 +626,17 @@ static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
			VERIFY(err, 0 == ion_map_iommu(me->iclient, handles[i],
					me->channel[cid].smmu.domain_id,
					0, SZ_4K, 0, &iova, &len, 0, 0));
			if (err)
				goto bail;
			VERIFY(err, (num << PAGE_SHIFT) <= len);
			if (err)
				goto bail;
			VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
			if (err)
				goto bail;
			rpra[i].buf.pv = pra[i].buf.pv;
			list[i].num = 1;
			pages[list[i].pgidx].addr = iova;
			pages[list[i].pgidx].size = len;
			pages[idx].addr = iova + (start - vma->vm_start);
			pages[idx].size = num << PAGE_SHIFT;
			continue;
		} else if (list[i].num) {
			rpra[i].buf.pv = pra[i].buf.pv;
@@ -675,8 +700,8 @@ static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
	}
	dmac_flush_range(rpra, (char *)rpra + used);
 bail:
	*abufs = obufs;
	*nbufs = bufs;
	ctx->abufs = obufs;
	ctx->nbufs = bufs;
	return err;
}

@@ -991,14 +1016,11 @@ static int fastrpc_internal_invoke(struct fastrpc_apps *me, uint32_t mode,
		VERIFY(err, 0 == get_dev(me, cid, &ctx->dev));
		if (err)
			goto bail;
		VERIFY(err, 0 == get_page_list(kernel, ctx->sc, ctx->pra,
					&ctx->dev->buf, &ctx->obuf, cid));
		VERIFY(err, 0 == get_page_list(kernel, ctx, cid));
		if (err)
			goto bail;
		ctx->rpra = (remote_arg_t *)ctx->obuf.virt;
		VERIFY(err, 0 == get_args(kernel, ctx->sc, ctx->pra, ctx->rpra,
				invoke->pra, &ctx->obuf, &ctx->abufs,
				&ctx->nbufs, ctx->fds, ctx->handles, cid));
		VERIFY(err, 0 == get_args(kernel, ctx, invoke->pra, cid));
		if (err)
			goto bail;
	}