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

Commit 604e5586 authored by Tharun Kumar Merugu's avatar Tharun Kumar Merugu
Browse files

msm: adsprpc: Use unsigned integer for length values



As the length datatype is signed, an attacker can both overflow
the calculation or supply a negative number to trick the check
into returning an chosen chunk. This can have undesired
consequences. Always use unsigned integer types for length
values.

Change-Id: Ifde2f0d35129014b976507f7723a319c53fabddf
Acked-by: default avatarThyagarajan Venkatanarayanan <venkatan@qti.qualcomm.com>
Signed-off-by: default avatarTharun Kumar Merugu <mtharu@codeaurora.org>
parent ce9aab8f
Loading
Loading
Loading
Loading
+103 −91
Original line number Original line Diff line number Diff line
@@ -84,11 +84,11 @@ static inline uint64_t buf_page_offset(uint64_t buf)
	return offset;
	return offset;
}
}


static inline int buf_num_pages(uint64_t buf, ssize_t len)
static inline uint64_t buf_num_pages(uint64_t buf, size_t len)
{
{
	uint64_t start = buf_page_start(buf) >> PAGE_SHIFT;
	uint64_t start = buf_page_start(buf) >> PAGE_SHIFT;
	uint64_t end = (((uint64_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
	uint64_t end = (((uint64_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
	int nPages = end - start + 1;
	uint64_t nPages = end - start + 1;
	return nPages;
	return nPages;
}
}


@@ -122,7 +122,7 @@ struct fastrpc_buf {
	struct fastrpc_file *fl;
	struct fastrpc_file *fl;
	void *virt;
	void *virt;
	uint64_t phys;
	uint64_t phys;
	ssize_t size;
	size_t size;
};
};


struct fastrpc_ctx_lst;
struct fastrpc_ctx_lst;
@@ -147,7 +147,7 @@ struct smq_invoke_ctx {
	int *fds;
	int *fds;
	struct fastrpc_mmap **maps;
	struct fastrpc_mmap **maps;
	struct fastrpc_buf *buf;
	struct fastrpc_buf *buf;
	ssize_t used;
	size_t used;
	struct fastrpc_file *fl;
	struct fastrpc_file *fl;
	uint32_t sc;
	uint32_t sc;
	struct overlap *overs;
	struct overlap *overs;
@@ -229,9 +229,9 @@ struct fastrpc_mmap {
	struct dma_buf_attachment *attach;
	struct dma_buf_attachment *attach;
	struct ion_handle *handle;
	struct ion_handle *handle;
	uint64_t phys;
	uint64_t phys;
	ssize_t size;
	size_t size;
	uintptr_t va;
	uintptr_t va;
	ssize_t len;
	size_t len;
	int refs;
	int refs;
	uintptr_t raddr;
	uintptr_t raddr;
	int uncached;
	int uncached;
@@ -276,7 +276,7 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = {


static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
{
{
	struct fastrpc_file *fl = buf == 0 ? 0 : buf->fl;
	struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl;
	int vmid;
	int vmid;


	if (!fl)
	if (!fl)
@@ -311,7 +311,8 @@ static void fastrpc_buf_list_free(struct fastrpc_file *fl)
	struct fastrpc_buf *buf, *free;
	struct fastrpc_buf *buf, *free;
	do {
	do {
		struct hlist_node *n;
		struct hlist_node *n;
		free = 0;

		free = NULL;
		spin_lock(&fl->hlock);
		spin_lock(&fl->hlock);
		hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) {
		hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) {
			hlist_del_init(&buf->hn);
			hlist_del_init(&buf->hn);
@@ -342,11 +343,13 @@ static void fastrpc_mmap_add(struct fastrpc_mmap *map)
}
}


static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va,
static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va,
			ssize_t len, int mflags, struct fastrpc_mmap **ppmap)
			size_t len, int mflags, struct fastrpc_mmap **ppmap)
{
{
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_mmap *match = 0, *map;
	struct fastrpc_mmap *match = NULL, *map = NULL;
	struct hlist_node *n;
	struct hlist_node *n;
	if ((va + len) < va)
		return -EOVERFLOW;
	if (mflags == ADSP_MMAP_HEAP_ADDR) {
	if (mflags == ADSP_MMAP_HEAP_ADDR) {
		spin_lock(&me->hlock);
		spin_lock(&me->hlock);
		hlist_for_each_entry_safe(map, n, &me->maps, hn) {
		hlist_for_each_entry_safe(map, n, &me->maps, hn) {
@@ -379,10 +382,10 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va,
	return -ENOTTY;
	return -ENOTTY;
}
}


static int dma_alloc_memory(phys_addr_t *region_start, ssize_t size)
static int dma_alloc_memory(phys_addr_t *region_start, size_t size)
{
{
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;
	void *vaddr = 0;
	void *vaddr = NULL;
	DEFINE_DMA_ATTRS(attrs);
	DEFINE_DMA_ATTRS(attrs);


	if (me->dev == NULL) {
	if (me->dev == NULL) {
@@ -402,9 +405,9 @@ static int dma_alloc_memory(phys_addr_t *region_start, ssize_t size)
}
}


static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
			       ssize_t len, struct fastrpc_mmap **ppmap)
			       size_t len, struct fastrpc_mmap **ppmap)
{
{
	struct fastrpc_mmap *match = 0, *map;
	struct fastrpc_mmap *match = NULL, *map = NULL;
	struct hlist_node *n;
	struct hlist_node *n;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;


@@ -511,11 +514,11 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map)
}
}


static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va,
static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va,
			ssize_t len, int mflags, struct fastrpc_mmap **ppmap)
			size_t len, int mflags, struct fastrpc_mmap **ppmap)
{
{
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_session_ctx *sess = fl->sctx;
	struct fastrpc_session_ctx *sess = fl->sctx;
	struct fastrpc_mmap *map = 0;
	struct fastrpc_mmap *map = NULL;
	struct dma_attrs attrs;
	struct dma_attrs attrs;
	phys_addr_t region_start = 0;
	phys_addr_t region_start = 0;
	unsigned long flags;
	unsigned long flags;
@@ -534,7 +537,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va,
	map->fd = fd;
	map->fd = fd;
	if (mflags == ADSP_MMAP_HEAP_ADDR) {
	if (mflags == ADSP_MMAP_HEAP_ADDR) {
		map->apps = me;
		map->apps = me;
		map->fl = 0;
		map->fl = NULL;
		VERIFY(err, !dma_alloc_memory(&region_start, len));
		VERIFY(err, !dma_alloc_memory(&region_start, len));
		if (err)
		if (err)
			goto bail;
			goto bail;
@@ -609,11 +612,11 @@ bail:
	return err;
	return err;
}
}


static int fastrpc_buf_alloc(struct fastrpc_file *fl, ssize_t size,
static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
			     struct fastrpc_buf **obuf)
			     struct fastrpc_buf **obuf)
{
{
	int err = 0, vmid;
	int err = 0, vmid;
	struct fastrpc_buf *buf = 0, *fr = 0;
	struct fastrpc_buf *buf = NULL, *fr = NULL;
	struct hlist_node *n;
	struct hlist_node *n;


	VERIFY(err, size > 0);
	VERIFY(err, size > 0);
@@ -633,13 +636,13 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, ssize_t size,
		*obuf = fr;
		*obuf = fr;
		return 0;
		return 0;
	}
	}
	buf = 0;
	buf = NULL;
	VERIFY(err, buf = kzalloc(sizeof(*buf), GFP_KERNEL));
	VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
	if (err)
	if (err)
		goto bail;
		goto bail;
	INIT_HLIST_NODE(&buf->hn);
	INIT_HLIST_NODE(&buf->hn);
	buf->fl = fl;
	buf->fl = fl;
	buf->virt = 0;
	buf->virt = NULL;
	buf->phys = 0;
	buf->phys = 0;
	buf->size = size;
	buf->size = size;
	buf->virt = dma_alloc_coherent(fl->sctx->dev, buf->size,
	buf->virt = dma_alloc_coherent(fl->sctx->dev, buf->size,
@@ -680,7 +683,7 @@ static int context_restore_interrupted(struct fastrpc_file *fl,
				       struct smq_invoke_ctx **po)
				       struct smq_invoke_ctx **po)
{
{
	int err = 0;
	int err = 0;
	struct smq_invoke_ctx *ctx = 0, *ictx = 0;
	struct smq_invoke_ctx *ctx = NULL, *ictx = NULL;
	struct hlist_node *n;
	struct hlist_node *n;
	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
	spin_lock(&fl->hlock);
	spin_lock(&fl->hlock);
@@ -733,7 +736,7 @@ static int context_build_overlap(struct smq_invoke_ctx *ctx)
		ctx->overs[i].raix = i;
		ctx->overs[i].raix = i;
		ctx->overps[i] = &ctx->overs[i];
		ctx->overps[i] = &ctx->overs[i];
	}
	}
	sort(ctx->overps, nbufs, sizeof(*ctx->overps), overlap_ptr_cmp, 0);
	sort(ctx->overps, nbufs, sizeof(*ctx->overps), overlap_ptr_cmp, NULL);
	max.start = 0;
	max.start = 0;
	max.end = 0;
	max.end = 0;
	for (i = 0; i < nbufs; ++i) {
	for (i = 0; i < nbufs; ++i) {
@@ -762,7 +765,8 @@ bail:
#define K_COPY_FROM_USER(err, kernel, dst, src, size) \
#define K_COPY_FROM_USER(err, kernel, dst, src, size) \
	do {\
	do {\
		if (!(kernel))\
		if (!(kernel))\
			VERIFY(err, 0 == copy_from_user((dst), (src),\
			VERIFY(err, 0 == copy_from_user((dst),\
			(void const __user *)(src),\
							(size)));\
							(size)));\
		else\
		else\
			memmove((dst), (src), (size));\
			memmove((dst), (src), (size));\
@@ -771,8 +775,8 @@ bail:
#define K_COPY_TO_USER(err, kernel, dst, src, size) \
#define K_COPY_TO_USER(err, kernel, dst, src, size) \
	do {\
	do {\
		if (!(kernel))\
		if (!(kernel))\
			VERIFY(err, 0 == copy_to_user((dst), (src),\
			VERIFY(err, 0 == copy_to_user((void __user *)(dst), \
						      (size)));\
						(src), (size)));\
		else\
		else\
			memmove((dst), (src), (size));\
			memmove((dst), (src), (size));\
	} while (0)
	} while (0)
@@ -785,7 +789,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
			 struct smq_invoke_ctx **po)
			 struct smq_invoke_ctx **po)
{
{
	int err = 0, bufs, size = 0;
	int err = 0, bufs, size = 0;
	struct smq_invoke_ctx *ctx = 0;
	struct smq_invoke_ctx *ctx = NULL;
	struct fastrpc_ctx_lst *clst = &fl->clst;
	struct fastrpc_ctx_lst *clst = &fl->clst;
	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;


@@ -795,7 +799,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
		sizeof(*ctx->overs) * (bufs) +
		sizeof(*ctx->overs) * (bufs) +
		sizeof(*ctx->overps) * (bufs);
		sizeof(*ctx->overps) * (bufs);


	VERIFY(err, ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL));
	VERIFY(err, NULL != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
	if (err)
	if (err)
		goto bail;
		goto bail;


@@ -808,7 +812,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
	ctx->overs = (struct overlap *)(&ctx->fds[bufs]);
	ctx->overs = (struct overlap *)(&ctx->fds[bufs]);
	ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
	ctx->overps = (struct overlap **)(&ctx->overs[bufs]);


	K_COPY_FROM_USER(err, kernel, ctx->lpra, invoke->pra,
	K_COPY_FROM_USER(err, kernel, (void *)ctx->lpra, invoke->pra,
					bufs * sizeof(*ctx->lpra));
					bufs * sizeof(*ctx->lpra));
	if (err)
	if (err)
		goto bail;
		goto bail;
@@ -909,10 +913,10 @@ static void context_list_ctor(struct fastrpc_ctx_lst *me)
static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
{
{
	struct fastrpc_ctx_lst *clst = &fl->clst;
	struct fastrpc_ctx_lst *clst = &fl->clst;
	struct smq_invoke_ctx *ictx = 0, *ctxfree;
	struct smq_invoke_ctx *ictx = NULL, *ctxfree;
	struct hlist_node *n;
	struct hlist_node *n;
	do {
	do {
		ctxfree = 0;
		ctxfree = NULL;
		spin_lock(&fl->hlock);
		spin_lock(&fl->hlock);
		hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
		hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
			hlist_del_init(&ictx->hn);
			hlist_del_init(&ictx->hn);
@@ -924,7 +928,7 @@ static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
			context_free(ctxfree);
			context_free(ctxfree);
	} while (ctxfree);
	} while (ctxfree);
	do {
	do {
		ctxfree = 0;
		ctxfree = NULL;
		spin_lock(&fl->hlock);
		spin_lock(&fl->hlock);
		hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) {
		hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) {
			hlist_del_init(&ictx->hn);
			hlist_del_init(&ictx->hn);
@@ -943,7 +947,7 @@ static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
	struct fastrpc_file *fl, *free;
	struct fastrpc_file *fl, *free;
	struct hlist_node *n;
	struct hlist_node *n;
	do {
	do {
		free = 0;
		free = NULL;
		spin_lock(&me->hlock);
		spin_lock(&me->hlock);
		hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
		hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
			hlist_del_init(&fl->hn);
			hlist_del_init(&fl->hn);
@@ -967,31 +971,32 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
	int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
	int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
	int bufs = inbufs + outbufs;
	int bufs = inbufs + outbufs;
	uintptr_t args;
	uintptr_t args;
	ssize_t rlen = 0, copylen = 0, metalen = 0;
	size_t rlen = 0, copylen = 0, metalen = 0;
	int i, inh, oix;
	int i, inh, oix;
	int err = 0;
	int err = 0;
	int mflags = 0;
	int mflags = 0;


	/* calculate size of the metadata */
	/* calculate size of the metadata */
	rpra = 0;
	rpra = NULL;
	list = smq_invoke_buf_start(rpra, sc);
	list = smq_invoke_buf_start(rpra, sc);
	pages = smq_phy_page_start(sc, list);
	pages = smq_phy_page_start(sc, list);
	ipage = pages;
	ipage = pages;


	for (i = 0; i < bufs; ++i) {
	for (i = 0; i < bufs; ++i) {
		uintptr_t buf = (uintptr_t)lpra[i].buf.pv;
		uintptr_t buf = (uintptr_t)lpra[i].buf.pv;
		ssize_t len = lpra[i].buf.len;
		size_t len = lpra[i].buf.len;
		if (ctx->fds[i])
		if (ctx->fds[i])
			fastrpc_mmap_create(ctx->fl, ctx->fds[i], buf, len,
			fastrpc_mmap_create(ctx->fl, ctx->fds[i], buf, len,
					    mflags, &ctx->maps[i]);
					    mflags, &ctx->maps[i]);
		ipage += 1;
		ipage += 1;
	}
	}
	metalen = copylen = (ssize_t)&ipage[0];
	metalen = copylen = (size_t)&ipage[0];
	/* calculate len requreed for copying */
	/* calculate len requreed for copying */
	for (oix = 0; oix < inbufs + outbufs; ++oix) {
	for (oix = 0; oix < inbufs + outbufs; ++oix) {
		int i = ctx->overps[oix]->raix;
		int i = ctx->overps[oix]->raix;
		uintptr_t mstart, mend;
		uintptr_t mstart, mend;
		ssize_t len = lpra[i].buf.len;
		size_t len = lpra[i].buf.len;

		if (!len)
		if (!len)
			continue;
			continue;
		if (ctx->maps[i])
		if (ctx->maps[i])
@@ -1024,7 +1029,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
	ipage = pages;
	ipage = pages;
	args = (uintptr_t)ctx->buf->virt + metalen;
	args = (uintptr_t)ctx->buf->virt + metalen;
	for (i = 0; i < bufs; ++i) {
	for (i = 0; i < bufs; ++i) {
		ssize_t len = lpra[i].buf.len;
		size_t len = lpra[i].buf.len;
		list[i].num = 0;
		list[i].num = 0;
		list[i].pgidx = 0;
		list[i].pgidx = 0;
		if (!len)
		if (!len)
@@ -1037,7 +1042,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
	for (i = 0; i < inbufs + outbufs; ++i) {
	for (i = 0; i < inbufs + outbufs; ++i) {
		struct fastrpc_mmap *map = ctx->maps[i];
		struct fastrpc_mmap *map = ctx->maps[i];
		uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
		uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
		ssize_t len = lpra[i].buf.len;
		size_t len = lpra[i].buf.len;
		rpra[i].buf.pv = 0;
		rpra[i].buf.pv = 0;
		rpra[i].buf.len = len;
		rpra[i].buf.len = len;
		if (!len)
		if (!len)
@@ -1045,7 +1050,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
		if (map) {
		if (map) {
			struct vm_area_struct *vma;
			struct vm_area_struct *vma;
			uintptr_t offset;
			uintptr_t offset;
			int num = buf_num_pages(buf, len);
			uint64_t num = buf_num_pages(buf, len);
			int idx = list[i].pgidx;
			int idx = list[i].pgidx;


			down_read(&current->mm->mmap_sem);
			down_read(&current->mm->mmap_sem);
@@ -1071,9 +1076,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
	for (oix = 0; oix < inbufs + outbufs; ++oix) {
	for (oix = 0; oix < inbufs + outbufs; ++oix) {
		int i = ctx->overps[oix]->raix;
		int i = ctx->overps[oix]->raix;
		struct fastrpc_mmap *map = ctx->maps[i];
		struct fastrpc_mmap *map = ctx->maps[i];
		ssize_t mlen;
		size_t mlen;
		uint64_t buf;
		uint64_t buf;
		ssize_t len = lpra[i].buf.len;
		size_t len = lpra[i].buf.len;

		if (!len)
		if (!len)
			continue;
			continue;
		if (map)
		if (map)
@@ -1153,7 +1159,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
				goto bail;
				goto bail;
		} else {
		} else {
			fastrpc_mmap_free(ctx->maps[i]);
			fastrpc_mmap_free(ctx->maps[i]);
			ctx->maps[i] = 0;
			ctx->maps[i] = NULL;
		}
		}
	}
	}
	size = sizeof(*rpra) * REMOTE_SCALARS_OUTHANDLES(sc);
	size = sizeof(*rpra) * REMOTE_SCALARS_OUTHANDLES(sc);
@@ -1252,7 +1258,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
	struct fastrpc_file *fl = ctx->fl;
	struct fastrpc_file *fl = ctx->fl;
	int err = 0, len;
	int err = 0, len;


	VERIFY(err, 0 != fl->apps->channel[fl->cid].chan);
	VERIFY(err, NULL != fl->apps->channel[fl->cid].chan);
	if (err)
	if (err)
		goto bail;
		goto bail;
	msg->pid = current->tgid;
	msg->pid = current->tgid;
@@ -1335,13 +1341,13 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
				   uint32_t kernel,
				   uint32_t kernel,
				   struct fastrpc_ioctl_invoke_fd *invokefd)
				   struct fastrpc_ioctl_invoke_fd *invokefd)
{
{
	struct smq_invoke_ctx *ctx = 0;
	struct smq_invoke_ctx *ctx = NULL;
	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
	struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
	int cid = fl->cid;
	int cid = fl->cid;
	int interrupted = 0;
	int interrupted = 0;
	int err = 0;
	int err = 0;


	VERIFY(err, fl->sctx);
	VERIFY(err, fl->sctx != NULL);
	if (err)
	if (err)
		goto bail;
		goto bail;
	VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS);
	VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS);
@@ -1410,7 +1416,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
	int err = 0;
	int err = 0;
	struct fastrpc_ioctl_invoke_fd ioctl;
	struct fastrpc_ioctl_invoke_fd ioctl;
	struct smq_phy_page pages[1];
	struct smq_phy_page pages[1];
	struct fastrpc_mmap *file = 0, *mem = 0;
	struct fastrpc_mmap *file = NULL, *mem = NULL;
	if (init->flags == FASTRPC_INIT_ATTACH) {
	if (init->flags == FASTRPC_INIT_ATTACH) {
		remote_arg_t ra[1];
		remote_arg_t ra[1];
		int tgid = current->tgid;
		int tgid = current->tgid;
@@ -1419,7 +1425,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
		ioctl.inv.handle = 1;
		ioctl.inv.handle = 1;
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
		ioctl.inv.pra = ra;
		ioctl.inv.pra = ra;
		ioctl.fds = 0;
		ioctl.fds = NULL;
		VERIFY(err, !(err = fastrpc_internal_invoke(fl,
		VERIFY(err, !(err = fastrpc_internal_invoke(fl,
			FASTRPC_MODE_PARALLEL, 1, &ioctl)));
			FASTRPC_MODE_PARALLEL, 1, &ioctl)));
		if (err)
		if (err)
@@ -1493,7 +1499,7 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
	remote_arg_t ra[1];
	remote_arg_t ra[1];
	int tgid = 0;
	int tgid = 0;


	VERIFY(err, fl->apps->channel[fl->cid].chan != 0);
	VERIFY(err, fl->apps->channel[fl->cid].chan != NULL);
	if (err)
	if (err)
		goto bail;
		goto bail;
	tgid = fl->tgid;
	tgid = fl->tgid;
@@ -1502,7 +1508,7 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
	ioctl.inv.handle = 1;
	ioctl.inv.handle = 1;
	ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
	ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
	ioctl.inv.pra = ra;
	ioctl.inv.pra = ra;
	ioctl.fds = 0;
	ioctl.fds = NULL;
	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
bail:
bail:
@@ -1547,7 +1553,7 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
	else
	else
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
	ioctl.inv.pra = ra;
	ioctl.inv.pra = ra;
	ioctl.fds = 0;
	ioctl.fds = NULL;
	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
	map->raddr = (uintptr_t)routargs.vaddrout;
	map->raddr = (uintptr_t)routargs.vaddrout;
@@ -1585,7 +1591,7 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl,
	ioctl.inv.handle = 1;
	ioctl.inv.handle = 1;
	ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1);
	ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1);
	ioctl.inv.pra = ra;
	ioctl.inv.pra = ra;
	ioctl.fds = 0;
	ioctl.fds = NULL;


	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
			FASTRPC_MODE_PARALLEL, 1, &ioctl)));
			FASTRPC_MODE_PARALLEL, 1, &ioctl)));
@@ -1612,7 +1618,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl,
	struct {
	struct {
		int pid;
		int pid;
		uintptr_t vaddrout;
		uintptr_t vaddrout;
		ssize_t size;
		size_t size;
	} inargs;
	} inargs;
	if (map->flags == ADSP_MMAP_HEAP_ADDR) {
	if (map->flags == ADSP_MMAP_HEAP_ADDR) {
		VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, map));
		VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, map));
@@ -1632,7 +1638,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl,
	else
	else
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
	ioctl.inv.pra = ra;
	ioctl.inv.pra = ra;
	ioctl.fds = 0;
	ioctl.fds = NULL;
	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
		FASTRPC_MODE_PARALLEL, 1, &ioctl)));
bail:
bail:
@@ -1641,7 +1647,7 @@ bail:


static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
{
{
	struct fastrpc_mmap *match = 0, *map = NULL;
	struct fastrpc_mmap *match = NULL, *map = NULL;
	struct hlist_node *n = NULL;
	struct hlist_node *n = NULL;
	int err = 0, ret = 0;
	int err = 0, ret = 0;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;
@@ -1682,7 +1688,7 @@ bail:
}
}


static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
			     ssize_t len, struct fastrpc_mmap **ppmap);
			     size_t len, struct fastrpc_mmap **ppmap);


static void fastrpc_mmap_add(struct fastrpc_mmap *map);
static void fastrpc_mmap_add(struct fastrpc_mmap *map);


@@ -1690,7 +1696,7 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl,
				   struct fastrpc_ioctl_munmap *ud)
				   struct fastrpc_ioctl_munmap *ud)
{
{
	int err = 0;
	int err = 0;
	struct fastrpc_mmap *map = 0;
	struct fastrpc_mmap *map = NULL;
	if (!fastrpc_mmap_remove(fl, ud->vaddrout, ud->size,
	if (!fastrpc_mmap_remove(fl, ud->vaddrout, ud->size,
				 &map)) {
				 &map)) {
		VERIFY(err, !fastrpc_munmap_on_dsp(fl, map));
		VERIFY(err, !fastrpc_munmap_on_dsp(fl, map));
@@ -1708,7 +1714,7 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl,
				 struct fastrpc_ioctl_mmap *ud)
				 struct fastrpc_ioctl_mmap *ud)
{
{


	struct fastrpc_mmap *map = 0;
	struct fastrpc_mmap *map = NULL;
	int err = 0;
	int err = 0;
	if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin, ud->size,
	if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin, ud->size,
			       ud->flags, &map))
			       ud->flags, &map))
@@ -1741,7 +1747,7 @@ static void fastrpc_channel_close(struct kref *kref)
		glink_unregister_link_state_cb(ctx->link_notify_handle);
		glink_unregister_link_state_cb(ctx->link_notify_handle);
		glink_close(ctx->chan);
		glink_close(ctx->chan);
	}
	}
	ctx->chan = 0;
	ctx->chan = NULL;
	mutex_unlock(&me->smd_mutex);
	mutex_unlock(&me->smd_mutex);
	cid = ctx - &gcinfo[0];
	cid = ctx - &gcinfo[0];
	pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
	pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
@@ -1753,7 +1759,7 @@ static void fastrpc_context_list_dtor(struct fastrpc_file *fl);
static int fastrpc_file_free(struct fastrpc_file *fl)
static int fastrpc_file_free(struct fastrpc_file *fl)
{
{
	struct hlist_node *n;
	struct hlist_node *n;
	struct fastrpc_mmap *map = 0;
	struct fastrpc_mmap *map = NULL;
	int cid;
	int cid;


	if (!fl)
	if (!fl)
@@ -1829,19 +1835,20 @@ static int fastrpc_session_free(struct fastrpc_channel_ctx *chan, int session)
	return err;
	return err;
}
}


bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv, size_t size)
static bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv,
						size_t size)
{
{
	if (0 != glink_queue_rx_intent(h, NULL, size))
	if (0 != glink_queue_rx_intent(h, NULL, size))
		return false;
		return false;
	return true;
	return true;
}
}


void fastrpc_glink_notify_tx_done(void *handle, const void *priv,
static void fastrpc_glink_notify_tx_done(void *handle, const void *priv,
		const void *pkt_priv, const void *ptr)
		const void *pkt_priv, const void *ptr)
{
{
}
}


void fastrpc_glink_notify_rx(void *handle, const void *priv,
static void fastrpc_glink_notify_rx(void *handle, const void *priv,
	const void *pkt_priv, const void *ptr, size_t size)
	const void *pkt_priv, const void *ptr, size_t size)
{
{
	struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr;
	struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr;
@@ -1855,7 +1862,8 @@ void fastrpc_glink_notify_rx(void *handle, const void *priv,
	glink_rx_done(handle, ptr, true);
	glink_rx_done(handle, ptr, true);
}
}


void fastrpc_glink_notify_state(void *handle, const void *priv, unsigned event)
static void fastrpc_glink_notify_state(void *handle, const void *priv,
				unsigned int event)
{
{
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;
	int cid = (int)(uintptr_t)priv;
	int cid = (int)(uintptr_t)priv;
@@ -1876,7 +1884,7 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
{
{
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
	struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
	struct fastrpc_fl *pfl = 0;
	struct fastrpc_fl *pfl = NULL;
	int session, cid;
	int session, cid;
	int err = 0;
	int err = 0;


@@ -1910,7 +1918,7 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
		}
		}
		me->pending_free++;
		me->pending_free++;
		mutex_unlock(&me->flfree_mutex);
		mutex_unlock(&me->flfree_mutex);
		file->private_data = 0;
		file->private_data = NULL;
	}
	}
bail:
bail:
	if (err) {
	if (err) {
@@ -1924,8 +1932,8 @@ bail:
static void file_free_work_handler(struct work_struct *w)
static void file_free_work_handler(struct work_struct *w)
{
{
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_fl *fl = 0, *freefl = 0;
	struct fastrpc_fl *fl = NULL, *freefl = NULL;
	struct hlist_node *n = 0;
	struct hlist_node *n = NULL;


	while (1) {
	while (1) {
		mutex_lock(&me->flfree_mutex);
		mutex_lock(&me->flfree_mutex);
@@ -2007,7 +2015,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
	int err = 0, session;
	int err = 0, session;
	int event;
	int event;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_file *fl = 0;
	struct fastrpc_file *fl = NULL;


	if (me->pending_free) {
	if (me->pending_free) {
		event = wait_event_interruptible_timeout(wait_queue,
		event = wait_event_interruptible_timeout(wait_queue,
@@ -2039,7 +2047,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)


	fl->ssrcount = me->channel[cid].ssrcount;
	fl->ssrcount = me->channel[cid].ssrcount;
	if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
	if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
	    (me->channel[cid].chan == 0)) {
	    (me->channel[cid].chan == NULL)) {
		if (me->glink) {
		if (me->glink) {
			VERIFY(err, 0 == fastrpc_glink_open(cid, me));
			VERIFY(err, 0 == fastrpc_glink_open(cid, me));
		} else {
		} else {
@@ -2055,7 +2063,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
		VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work,
		VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work,
							RPC_TIMEOUT));
							RPC_TIMEOUT));
		if (err) {
		if (err) {
			me->channel[cid].chan = 0;
			me->channel[cid].chan = NULL;
			goto bail;
			goto bail;
		}
		}
		kref_init(&me->channel[cid].kref);
		kref_init(&me->channel[cid].kref);
@@ -2114,7 +2122,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
		p.invokefd.fds = 0;
		p.invokefd.fds = 0;
		size = (ioctl_num == FASTRPC_IOCTL_INVOKE) ?
		size = (ioctl_num == FASTRPC_IOCTL_INVOKE) ?
				sizeof(p.invokefd.inv) : sizeof(p.invokefd);
				sizeof(p.invokefd.inv) : sizeof(p.invokefd);
		VERIFY(err, 0 == copy_from_user(&p.invokefd, param, size));
		K_COPY_FROM_USER(err, 0, &p.invokefd, param, size);
		if (err)
		if (err)
			goto bail;
			goto bail;
		VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode,
		VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode,
@@ -2123,20 +2131,20 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
			goto bail;
			goto bail;
		break;
		break;
	case FASTRPC_IOCTL_MMAP:
	case FASTRPC_IOCTL_MMAP:
		VERIFY(err, 0 == copy_from_user(&p.mmap, param,
		K_COPY_FROM_USER(err, 0, &p.mmap, param,
						sizeof(p.mmap)));
						sizeof(p.mmap));
		if (err)
		if (err)
			goto bail;
			goto bail;
		VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
		VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
		if (err)
		if (err)
			goto bail;
			goto bail;
		VERIFY(err, 0 == copy_to_user(param, &p.mmap, sizeof(p.mmap)));
		K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap));
		if (err)
		if (err)
			goto bail;
			goto bail;
		break;
		break;
	case FASTRPC_IOCTL_MUNMAP:
	case FASTRPC_IOCTL_MUNMAP:
		VERIFY(err, 0 == copy_from_user(&p.munmap, param,
		K_COPY_FROM_USER(err, 0, &p.munmap, param,
						sizeof(p.munmap)));
						sizeof(p.munmap));
		if (err)
		if (err)
			goto bail;
			goto bail;
		VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
		VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
@@ -2156,10 +2164,13 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
		}
		}
		break;
		break;
	case FASTRPC_IOCTL_GETINFO:
	case FASTRPC_IOCTL_GETINFO:
	    K_COPY_FROM_USER(err, 0, &info, param, sizeof(info));
		if (err)
			goto bail;
		VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
		VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
		if (err)
		if (err)
			goto bail;
			goto bail;
		VERIFY(err, 0 == copy_to_user(param, &info, sizeof(info)));
		K_COPY_TO_USER(err, 0, param, &info, sizeof(info));
		if (err)
		if (err)
			goto bail;
			goto bail;
		break;
		break;
@@ -2203,7 +2214,7 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
			} else {
			} else {
				smd_close(ctx->chan);
				smd_close(ctx->chan);
			}
			}
			ctx->chan = 0;
			ctx->chan = NULL;
			pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
			pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
				 gcinfo[cid].name, MAJOR(me->dev_no), cid);
				 gcinfo[cid].name, MAJOR(me->dev_no), cid);
		}
		}
@@ -2259,7 +2270,8 @@ static int fastrpc_cb_probe(struct device *dev)
	int err = 0, i;
	int err = 0, i;
	int disable_htw = 1;
	int disable_htw = 1;


	VERIFY(err, 0 != (name = of_get_property(dev->of_node, "label", NULL)));
	VERIFY(err, NULL != (name = of_get_property(dev->of_node,
					 "label", NULL)));
	if (err)
	if (err)
		goto bail;
		goto bail;
	for (i = 0; i < NUM_CHANNELS; i++) {
	for (i = 0; i < NUM_CHANNELS; i++) {
@@ -2306,11 +2318,11 @@ static int fastrpc_cb_legacy_probe(struct device *dev)
{
{
	struct device_node *domains_child_node = NULL;
	struct device_node *domains_child_node = NULL;
	struct device_node *ctx_node = NULL;
	struct device_node *ctx_node = NULL;
	struct fastrpc_channel_ctx *chan;
	struct fastrpc_channel_ctx *chan = NULL;
	struct fastrpc_session_ctx *first_sess, *sess;
	struct fastrpc_session_ctx *first_sess = NULL, *sess = NULL;
	const char *name;
	const char *name = NULL;
	unsigned int *range = 0, range_size = 0;
	unsigned int *range = NULL, range_size = 0;
	unsigned int *sids = 0, sids_size = 0;
	unsigned int *sids = NULL, sids_size = 0;
	int err = 0, ret = 0, i;
	int err = 0, ret = 0, i;
	int disable_htw = 1;
	int disable_htw = 1;


@@ -2485,17 +2497,17 @@ static void fastrpc_deinit(void)
		if (chan->chan) {
		if (chan->chan) {
			kref_put_mutex(&chan->kref,
			kref_put_mutex(&chan->kref,
				fastrpc_channel_close, &me->smd_mutex);
				fastrpc_channel_close, &me->smd_mutex);
			chan->chan = 0;
			chan->chan = NULL;
		}
		}
		for (j = 0; j < NUM_SESSIONS; j++) {
		for (j = 0; j < NUM_SESSIONS; j++) {
			struct fastrpc_session_ctx *sess = &chan->session[j];
			struct fastrpc_session_ctx *sess = &chan->session[j];
			if (sess->smmu.enabled) {
			if (sess->smmu.enabled) {
				arm_iommu_detach_device(sess->dev);
				arm_iommu_detach_device(sess->dev);
				sess->dev = 0;
				sess->dev = NULL;
			}
			}
			if (sess->smmu.mapping) {
			if (sess->smmu.mapping) {
				arm_iommu_release_mapping(sess->smmu.mapping);
				arm_iommu_release_mapping(sess->smmu.mapping);
				sess->smmu.mapping = 0;
				sess->smmu.mapping = NULL;
			}
			}
		}
		}
	}
	}
@@ -2553,7 +2565,7 @@ static int __init fastrpc_device_init(void)
		me->channel[i].ssrcount = 0;
		me->channel[i].ssrcount = 0;
		me->channel[i].prevssrcount = 0;
		me->channel[i].prevssrcount = 0;
		me->channel[i].ramdumpenabled = 0;
		me->channel[i].ramdumpenabled = 0;
		me->channel[i].remoteheap_ramdump_dev = 0;
		me->channel[i].remoteheap_ramdump_dev = NULL;
		me->channel[i].nb.notifier_call = fastrpc_restart_notifier_cb;
		me->channel[i].nb.notifier_call = fastrpc_restart_notifier_cb;
		me->channel[i].handle = subsys_notif_register_notifier(
		me->channel[i].handle = subsys_notif_register_notifier(
							gcinfo[i].subsys,
							gcinfo[i].subsys,
+7 −7
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -33,7 +33,7 @@


struct compat_remote_buf {
struct compat_remote_buf {
	compat_uptr_t pv;	/* buffer pointer */
	compat_uptr_t pv;	/* buffer pointer */
	compat_ssize_t len;	/* length of buffer */
	compat_size_t len;	/* length of buffer */
};
};


union compat_remote_arg {
union compat_remote_arg {
@@ -56,13 +56,13 @@ struct compat_fastrpc_ioctl_mmap {
	compat_int_t fd;	/* ion fd */
	compat_int_t fd;	/* ion fd */
	compat_uint_t flags;	/* flags for dsp to map with */
	compat_uint_t flags;	/* flags for dsp to map with */
	compat_uptr_t vaddrin;	/* optional virtual address */
	compat_uptr_t vaddrin;	/* optional virtual address */
	compat_ssize_t size;	/* size */
	compat_size_t size;	/* size */
	compat_uptr_t vaddrout;	/* dsps virtual address */
	compat_uptr_t vaddrout;	/* dsps virtual address */
};
};


struct compat_fastrpc_ioctl_munmap {
struct compat_fastrpc_ioctl_munmap {
	compat_uptr_t vaddrout;	/* address to unmap */
	compat_uptr_t vaddrout;	/* address to unmap */
	compat_ssize_t size;	/* size */
	compat_size_t size;	/* size */
};
};


struct compat_fastrpc_ioctl_init {
struct compat_fastrpc_ioctl_init {
@@ -81,7 +81,7 @@ static int compat_get_fastrpc_ioctl_invoke(
			unsigned int cmd)
			unsigned int cmd)
{
{
	compat_uint_t u, sc;
	compat_uint_t u, sc;
	compat_ssize_t s;
	compat_size_t s;
	compat_uptr_t p;
	compat_uptr_t p;
	struct fastrpc_ioctl_invoke_fd *inv;
	struct fastrpc_ioctl_invoke_fd *inv;
	union compat_remote_arg *pra32;
	union compat_remote_arg *pra32;
@@ -164,7 +164,7 @@ static int compat_get_fastrpc_ioctl_mmap(
{
{
	compat_uint_t u;
	compat_uint_t u;
	compat_int_t i;
	compat_int_t i;
	compat_ssize_t s;
	compat_size_t s;
	compat_uptr_t p;
	compat_uptr_t p;
	int err;
	int err;


@@ -198,7 +198,7 @@ static int compat_get_fastrpc_ioctl_munmap(
			struct fastrpc_ioctl_munmap __user *unmap)
			struct fastrpc_ioctl_munmap __user *unmap)
{
{
	compat_uptr_t p;
	compat_uptr_t p;
	compat_ssize_t s;
	compat_size_t s;
	int err;
	int err;


	err = get_user(p, &unmap32->vaddrout);
	err = get_user(p, &unmap32->vaddrout);
+13 −12
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -95,7 +95,7 @@ do {\


struct remote_buf64 {
struct remote_buf64 {
	uint64_t pv;
	uint64_t pv;
	int64_t len;
	uint64_t len;
};
};


union remote_arg64 {
union remote_arg64 {
@@ -107,7 +107,7 @@ union remote_arg64 {


struct remote_buf {
struct remote_buf {
	void *pv;		/* buffer pointer */
	void *pv;		/* buffer pointer */
	ssize_t len;		/* length of buffer */
	size_t len;		/* length of buffer */
};
};


union remote_arg {
union remote_arg {
@@ -128,25 +128,25 @@ struct fastrpc_ioctl_invoke_fd {


struct fastrpc_ioctl_init {
struct fastrpc_ioctl_init {
	uint32_t flags;		/* one of FASTRPC_INIT_* macros */
	uint32_t flags;		/* one of FASTRPC_INIT_* macros */
	uintptr_t __user file;	/* pointer to elf file */
	uintptr_t file;		/* pointer to elf file */
	int32_t filelen;	/* elf file length */
	uint32_t filelen;	/* elf file length */
	int32_t filefd;		/* ION fd for the file */
	int32_t filefd;		/* ION fd for the file */
	uintptr_t __user mem;	/* mem for the PD */
	uintptr_t mem;		/* mem for the PD */
	int32_t memlen;		/* mem length */
	uint32_t memlen;	/* mem length */
	int32_t memfd;		/* ION fd for the mem */
	int32_t memfd;		/* ION fd for the mem */
};
};


struct fastrpc_ioctl_munmap {
struct fastrpc_ioctl_munmap {
	uintptr_t vaddrout;	/* address to unmap */
	uintptr_t vaddrout;	/* address to unmap */
	ssize_t size;		/* size */
	size_t size;		/* size */
};
};




struct fastrpc_ioctl_mmap {
struct fastrpc_ioctl_mmap {
	int fd;				/* ion fd */
	int fd;				/* ion fd */
	uint32_t flags;			/* flags for dsp to map with */
	uint32_t flags;			/* flags for dsp to map with */
	uintptr_t __user *vaddrin;	/* optional virtual address */
	uintptr_t vaddrin;		/* optional virtual address */
	ssize_t size;			/* size */
	size_t size;			/* size */
	uintptr_t vaddrout;		/* dsps virtual address */
	uintptr_t vaddrout;		/* dsps virtual address */
};
};


@@ -185,14 +185,15 @@ struct smq_invoke_rsp {
static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg64_t *pra,
static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg64_t *pra,
							uint32_t sc)
							uint32_t sc)
{
{
	int len = REMOTE_SCALARS_LENGTH(sc);
	uint32_t len = REMOTE_SCALARS_LENGTH(sc);

	return (struct smq_invoke_buf *)(&pra[len]);
	return (struct smq_invoke_buf *)(&pra[len]);
}
}


static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc,
static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc,
						struct smq_invoke_buf *buf)
						struct smq_invoke_buf *buf)
{
{
	int nTotal = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc);
	uint32_t nTotal = REMOTE_SCALARS_INBUFS(sc)+REMOTE_SCALARS_OUTBUFS(sc);
	return (struct smq_phy_page *)(&buf[nTotal]);
	return (struct smq_phy_page *)(&buf[nTotal]);
}
}