Explorar o código

Merge cfd8b01ad31f2a17a918a3afdbf08c9876348edd on remote branch

Change-Id: I9528b6ae8030cc4d97315c53db8212084d0d5960
Linux Build Service Account hai 7 meses
pai
achega
3c7891e07a
Modificáronse 3 ficheiros con 146 adicións e 98 borrados
  1. 60 41
      dsp/adsprpc.c
  2. 84 57
      dsp/adsprpc_compat.c
  3. 2 0
      dsp/adsprpc_shared.h

+ 60 - 41
dsp/adsprpc.c

@@ -955,6 +955,8 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, int fd, uintptr_t va,
 			map->refs == 1 &&
 			/* Remove map only if it isn't being used in any pending RPC calls */
 			!map->ctx_refs &&
+			/* Remove map only if it isn't being used by DSP */
+			!map->dma_handle_refs &&
 			/* Skip unmap if it is fastrpc shell memory */
 			!map->is_filemap) {
 			match = map;
@@ -994,8 +996,9 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
 	if (map->flags == ADSP_MMAP_HEAP_ADDR ||
 				map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
 		spin_lock_irqsave(&me->hlock, irq_flags);
-		map->refs--;
-		if (!map->refs && !map->is_persistent && !map->ctx_refs)
+		if (map->refs)
+			map->refs--;
+		if (!map->refs && !map->is_persistent)
 			hlist_del_init(&map->hn);
 		if (map->refs > 0) {
 			ADSPRPC_WARN(
@@ -1008,10 +1011,14 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
 			map->in_use = false;
 		spin_unlock_irqrestore(&me->hlock, irq_flags);
 	} else {
-		map->refs--;
-		if (!map->refs && !map->ctx_refs)
+		if (map->refs)
+			map->refs--;
+		/* flags is passed as 1 during fastrpc_file_free (ie process exit),
+		 * so that maps will be cleared even though references are present.
+		 */
+		if (flags || (!map->refs && !map->ctx_refs && !map->dma_handle_refs))
 			hlist_del_init(&map->hn);
-		if (map->refs > 0 && !flags)
+		else
 			return;
 	}
 	if (map->flags == ADSP_MMAP_HEAP_ADDR ||
@@ -1887,7 +1894,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
 	}
 
 	if (invokefd->fds) {
-		K_COPY_FROM_USER(err, kernel, ctx->fds, invokefd->fds,
+		K_COPY_FROM_USER(err, kernel_msg, ctx->fds, invokefd->fds,
 						bufs * sizeof(*ctx->fds));
 		if (err) {
 			ADSPRPC_ERR(
@@ -1900,7 +1907,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
 		ctx->fds = NULL;
 	}
 	if (invokefd->attrs) {
-		K_COPY_FROM_USER(err, kernel, ctx->attrs, invokefd->attrs,
+		K_COPY_FROM_USER(err, kernel_msg, ctx->attrs, invokefd->attrs,
 						bufs * sizeof(*ctx->attrs));
 		if (err) {
 			ADSPRPC_ERR(
@@ -1945,7 +1952,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
 		ctx->perf->tid = fl->tgid;
 	}
 	if (invokefd->job) {
-		K_COPY_FROM_USER(err, kernel, &ctx->asyncjob, invokefd->job,
+		K_COPY_FROM_USER(err, kernel_msg, &ctx->asyncjob, invokefd->job,
 						sizeof(ctx->asyncjob));
 		if (err)
 			goto bail;
@@ -2501,21 +2508,22 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
 		if (err) {
 			for (j = bufs; j < i; j++) {
 				/*
-				 * Due to error decrement ctx refs count before mmap free
+				 * Due to error decrement  refs count before mmap free
 				 * for each in/out handle, if map created
 				 */
-				if (ctx->maps[j] && ctx->maps[j]->ctx_refs)
-					ctx->maps[j]->ctx_refs--;
-				fastrpc_mmap_free(ctx->maps[j], 0);
+				if (ctx->maps[j] && ctx->maps[j]->dma_handle_refs) {
+					ctx->maps[j]->dma_handle_refs--;
+					fastrpc_mmap_free(ctx->maps[j], 0);
+				}
 			}
 			mutex_unlock(&ctx->fl->map_mutex);
 			goto bail;
 		} else if (ctx->maps[i]) {
 			/*
-			 * Increment ctx refs count for in/out handle if map created
+			 * Increment  refs count for in/out handle if map created
 			 * and no error, indicate map under use in remote call
 			 */
-			ctx->maps[i]->ctx_refs++;
+			ctx->maps[i]->dma_handle_refs++;
 		}
 		ipage += 1;
 	}
@@ -2667,14 +2675,33 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
 		rpra[i].buf.pv = buf;
 	}
 	PERF_END);
+	/* Since we are not holidng map_mutex during get args whole time
+	 * it is possible that dma handle map may be removed by some invalid
+	 * fd passed by DSP. Inside the lock check if the map present or not
+	 */
+	mutex_lock(&ctx->fl->map_mutex);
 	for (i = bufs; i < bufs + handles; ++i) {
-		struct fastrpc_mmap *map = ctx->maps[i];
+		struct fastrpc_mmap *mmap = NULL;
+		/* check if map  was created */
+		if (ctx->maps[i]) {
+			/* check if map still exist */
+			if (!fastrpc_mmap_find(ctx->fl, ctx->fds[i], NULL, 0, 0,
+				0, 0, &mmap)) {
+				if (mmap) {
+					pages[i].addr = mmap->phys;
+					pages[i].size = mmap->size;
+				}
 
-		if (map) {
-			pages[i].addr = map->phys;
-			pages[i].size = map->size;
+			} else {
+				/* map already freed by some other call */
+				mutex_unlock(&ctx->fl->map_mutex);
+				ADSPRPC_ERR("could not find map associated with dma hadle fd %d \n",
+					ctx->fds[i]);
+				goto bail;
+			}
 		}
 	}
+	mutex_unlock(&ctx->fl->map_mutex);
 	fdlist = (uint64_t *)&pages[bufs + handles];
 	crclist = (uint32_t *)&fdlist[M_FDLIST];
 	/* reset fds, crc and early wakeup hint memory */
@@ -2883,9 +2910,10 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
 			 * Decrement ctx refs count before mmap free,
 			 * indicate remote call no longer using it
 			 */
-			if (mmap && mmap->ctx_refs)
-				mmap->ctx_refs--;
-			fastrpc_mmap_free(mmap, 0);
+			if (mmap && mmap->dma_handle_refs) {
+				mmap->dma_handle_refs = 0;
+				fastrpc_mmap_free(mmap, 0);
+			}
 		}
 	}
 	mutex_unlock(&ctx->fl->map_mutex);
@@ -3896,7 +3924,7 @@ int fastrpc_internal_invoke2(struct fastrpc_file *fl,
 			err = -EBADE;
 			goto bail;
 		}
-		K_COPY_FROM_USER(err, is_compat, &p.user_concurrency,
+		K_COPY_FROM_USER(err, 0, &p.user_concurrency,
 				(void *)inv2->invparam, size);
 		if (err)
 			goto bail;
@@ -6001,16 +6029,8 @@ skip_dmainvoke_wait:
 	is_locked = false;
 	spin_unlock_irqrestore(&fl->apps->hlock, irq_flags);
 
-	if (!fl->sctx) {
-		spin_lock_irqsave(&me->hlock, irq_flags);
-		/* Reset the tgid usage to false */
-		if (fl->tgid_frpc != -1)
-			frpc_tgid_usage_array[fl->tgid_frpc] = false;
-		spin_unlock_irqrestore(&me->hlock, irq_flags);
-		kfree(fl);
-		fl = NULL;
-		return;
-	}
+	if (!fl->sctx)
+		goto bail;
 
 	//Dummy wake up to exit Async worker thread
 	spin_lock_irqsave(&fl->aqlock, flags);
@@ -6064,23 +6084,22 @@ skip_dmainvoke_wait:
 	if (fl->device && is_driver_closed)
 		device_unregister(&fl->device->dev);
 
-	spin_lock_irqsave(&me->hlock, irq_flags);
-	/* Reset the tgid usage to false */
-	if (fl->tgid_frpc != -1)
-		frpc_tgid_usage_array[fl->tgid_frpc] = false;
-	spin_unlock_irqrestore(&me->hlock, irq_flags);
-
 	VERIFY(err, VALID_FASTRPC_CID(cid));
 	if (!err && fl->sctx)
 		fastrpc_session_free(&fl->apps->channel[cid], fl->sctx);
 	if (!err && fl->secsctx)
 		fastrpc_session_free(&fl->apps->channel[cid], fl->secsctx);
-
 	for (i = 0; i < (DSPSIGNAL_NUM_SIGNALS / DSPSIGNAL_GROUP_SIZE); i++)
 		kfree(fl->signal_groups[i]);
-	mutex_destroy(&fl->signal_create_mutex);
-
 	fastrpc_remote_buf_list_free(fl);
+
+bail:
+	spin_lock_irqsave(&me->hlock, irq_flags);
+	/* Reset the tgid usage to false */
+	if (fl->tgid_frpc != -1)
+		frpc_tgid_usage_array[fl->tgid_frpc] = false;
+	spin_unlock_irqrestore(&me->hlock, irq_flags);
+	mutex_destroy(&fl->signal_create_mutex);
 	mutex_destroy(&fl->map_mutex);
 	mutex_destroy(&fl->internal_map_mutex);
 	kfree(fl->dev_pm_qos_req);

+ 84 - 57
dsp/adsprpc_compat.c

@@ -280,7 +280,6 @@ static int compat_get_fastrpc_ioctl_invoke(
 	if (err)
 		return err;
 	pra32 = compat_ptr(p);
-	pra = (union remote_arg *)(inv + 1);
 	for (j = 0; j < len; j++) {
 		err |= get_user(p, &pra32[j].buf.pv);
 		memcpy((uintptr_t *)&pra[j].buf.pv, &p, sizeof(p));
@@ -288,12 +287,11 @@ static int compat_get_fastrpc_ioctl_invoke(
 		memcpy(&pra[j].buf.len, &s, sizeof(s));
 	}
 
-	inv->fds = NULL;
 	if (cmd != COMPAT_FASTRPC_IOCTL_INVOKE) {
 		err |= get_user(p, &inv32->fds);
 		memcpy(&inv->fds, &p, sizeof(p));
 	}
-	inv->attrs = NULL;
+
 	if ((cmd == COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS) ||
 		(cmd == COMPAT_FASTRPC_IOCTL_INVOKE_CRC) ||
 		(cmd == COMPAT_FASTRPC_IOCTL_INVOKE_PERF) ||
@@ -301,19 +299,17 @@ static int compat_get_fastrpc_ioctl_invoke(
 		err |= get_user(p, &inv32->attrs);
 		memcpy(&inv->attrs, &p, sizeof(p));
 	}
-	inv->crc = NULL;
+
 	if ((cmd == COMPAT_FASTRPC_IOCTL_INVOKE_CRC) ||
 		(cmd == COMPAT_FASTRPC_IOCTL_INVOKE_PERF)) {
 		err |= get_user(p, &inv32->crc);
 		memcpy(&inv->crc, &p, sizeof(p));
 	}
-	inv->job = NULL;
+
 	if (cmd == FASTRPC_INVOKE2_ASYNC) {
 		err |= get_user(p, &inv32->job);
 		memcpy(&inv->job, &p, sizeof(p));
 	}
-	inv->perf_kernel = NULL;
-	inv->perf_dsp = NULL;
 
 	if ((cmd == COMPAT_FASTRPC_IOCTL_INVOKE_PERF) || (cmd == FASTRPC_INVOKE2_ASYNC)) {
 		err |= get_user(k, &inv32->perf_kernel);
@@ -328,7 +324,7 @@ static int compat_fastrpc_ioctl_invoke(struct file *filp,
 		unsigned int cmd, unsigned long arg)
 {
 	struct compat_fastrpc_ioctl_invoke_async __user *inv32;
-	struct fastrpc_ioctl_invoke_async *inv;
+	struct fastrpc_ioctl_invoke_async *inv = NULL;
 	compat_uint_t sc = 0;
 	int err = 0, len = 0;
 	struct fastrpc_file *fl = (struct fastrpc_file *)filp->private_data;
@@ -338,16 +334,20 @@ static int compat_fastrpc_ioctl_invoke(struct file *filp,
 	if (err)
 		return err;
 	len = REMOTE_SCALARS_LENGTH(sc);
-	VERIFY(err, NULL != (inv = kmalloc(
+	VERIFY(err, NULL != (inv = kzalloc(
 		sizeof(*inv) + len * sizeof(union remote_arg), GFP_KERNEL)));
 	if (err)
 		return -EFAULT;
+
 	VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(inv32,
 						inv, cmd, sc));
-	if (err)
+	if (err) {
+		kfree(inv);
 		return err;
+	}
 	VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
 						fl->mode, COMPAT_MSG, inv)));
+	kfree(inv);
 	return err;
 }
 
@@ -386,7 +386,7 @@ static int compat_get_fastrpc_ioctl_invoke2(
 		if (err)
 			goto bail;
 		len = REMOTE_SCALARS_LENGTH(sc);
-		VERIFY(err, NULL != (inv2_user = kmalloc(
+		VERIFY(err, NULL != (inv2_user = kzalloc(
 				sizeof(*inv2_user) + sizeof(*asyncinv_user) +
 					len * sizeof(union remote_arg), GFP_KERNEL)));
 		if (err) {
@@ -402,11 +402,8 @@ static int compat_get_fastrpc_ioctl_invoke2(
 			if (err)
 				goto bail;
 
-			asyncinv_user->job = NULL;
 			err |= get_user(p, &lasync32_old->job);
 			memcpy(&asyncinv_user->job, &p, sizeof(p));
-			asyncinv_user->perf_kernel = NULL;
-			asyncinv_user->perf_dsp = NULL;
 		} else {
 			VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(lasync32,
 							asyncinv_user, req, sc));
@@ -416,8 +413,6 @@ static int compat_get_fastrpc_ioctl_invoke2(
 		memcpy(&inv2_user->req, &req, sizeof(req));
 		inv2_user->invparam = (uintptr_t)asyncinv_user;
 		inv2_user->size = sizeof(*asyncinv_user);
-		if (err)
-			goto bail;
 		break;
 	}
 	case FASTRPC_INVOKE2_ASYNC_RESPONSE:
@@ -448,7 +443,7 @@ static int compat_get_fastrpc_ioctl_invoke2(
 				goto bail;
 			}
 		}
-		VERIFY(err, NULL != (inv2_user = kmalloc(
+		VERIFY(err, NULL != (inv2_user = kzalloc(
 							sizeof(*inv2_user), GFP_KERNEL)));
 		if (err) {
 			err = -EFAULT;
@@ -457,16 +452,15 @@ static int compat_get_fastrpc_ioctl_invoke2(
 		memcpy(&inv2_user->req, &req, sizeof(req));
 		memcpy(&inv2_user->invparam, &pparam, sizeof(pparam));
 		memcpy(&inv2_user->size, &size, sizeof(size));
-		if (err)
-			goto bail;
 		break;
 	}
 	default:
 		err = -ENOTTY;
 		break;
 	}
-	*inva = inv2_user;
+
 bail:
+	*inva = inv2_user;
 	return err;
 }
 
@@ -474,17 +468,20 @@ static int compat_fastrpc_ioctl_invoke2(struct file *filp,
 		unsigned int cmd, unsigned long arg)
 {
 	struct compat_fastrpc_ioctl_invoke2 __user *inv32;
-	struct fastrpc_ioctl_invoke2 *inv;
+	struct fastrpc_ioctl_invoke2 *inv = NULL;
 	int err = 0;
 	struct fastrpc_file *fl = (struct fastrpc_file *)filp->private_data;
 
 	inv32 = compat_ptr(arg);
 	VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke2(inv32,
 							&inv, cmd));
-	if (err)
+	if (err) {
+		kfree(inv);
 		return err;
+	}
 
 	VERIFY(err, 0 == (err = fastrpc_internal_invoke2(fl, inv, true)));
+	kfree(inv);
 	return err;
 }
 
@@ -740,28 +737,30 @@ static int compat_fastrpc_control(struct fastrpc_file *fl,
 {
 	int err = 0;
 	struct compat_fastrpc_ioctl_control __user *ctrl32;
-	struct fastrpc_ioctl_control *ctrl;
+	struct fastrpc_ioctl_control *ctrl = NULL;
 	compat_uptr_t p;
 
 	ctrl32 = compat_ptr(arg);
-	VERIFY(err, NULL != (ctrl = kmalloc(
+	VERIFY(err, NULL != (ctrl = kzalloc(
 						sizeof(*ctrl), GFP_KERNEL)));
 	if (err)
 		return -EFAULT;
 	VERIFY(err, 0 == compat_get_fastrpc_ioctl_control(ctrl32,
 						ctrl));
 	if (err)
-		return err;
+		goto bail;
 	VERIFY(err, 0 == (err = fastrpc_internal_control(fl, ctrl)));
 	if (err)
-		return err;
+		goto bail;
 	err = get_user(p, &ctrl32->req);
 	if (err)
-		return err;
+		goto bail;
 	if (p == FASTRPC_CONTROL_KALLOC) {
 		memcpy(&p, &ctrl->kalloc.kalloc_support, sizeof(ctrl->kalloc.kalloc_support));
 		err |= put_user(p, &ctrl32->kalloc.kalloc_support);
 	}
+bail:
+	kfree(ctrl);
 	return err;
 }
 
@@ -775,7 +774,7 @@ static int compat_fastrpc_get_dsp_info(struct fastrpc_file *fl,
 	size_t info_size = 0;
 
 	info32 = compat_ptr(arg);
-	VERIFY(err, NULL != (info = kmalloc(
+	VERIFY(err, NULL != (info = kzalloc(
 				sizeof(*info), GFP_KERNEL)));
 	info_size = sizeof(*info);
 	if (err) {
@@ -784,20 +783,21 @@ static int compat_fastrpc_get_dsp_info(struct fastrpc_file *fl,
 	}
 	err = get_user(u, &info32->domain);
 	if (err)
-		return err;
+		goto bail;
 	memcpy(&info->domain, &u, sizeof(info->domain));
 
 	err = get_user(u, &info32->attribute_ID);
 	if (err)
-		return err;
+		goto bail;
 	memcpy(&info->attribute_ID, &u, sizeof(info->attribute_ID));
 
 	err = fastrpc_get_info_from_kernel(info, fl);
 	if (err)
-		return err;
+		goto bail;
 
 	err = compat_put_fastrpc_ioctl_get_dsp_info(info32, info);
-
+bail:
+	kfree(info);
 	return err;
 }
 
@@ -810,95 +810,112 @@ static inline long compat_fastrpc_mmap_device_ioctl(struct fastrpc_file *fl,
 	case COMPAT_FASTRPC_IOCTL_MEM_MAP:
 	{
 		struct compat_fastrpc_ioctl_mem_map __user *map32;
-		struct fastrpc_ioctl_mem_map *map;
+		struct fastrpc_ioctl_mem_map *map = NULL;
 
 		map32 = compat_ptr(arg);
-		VERIFY(err, NULL != (map = kmalloc(
+		VERIFY(err, NULL != (map = kzalloc(
 			sizeof(*map), GFP_KERNEL)));
 		if (err)
 			return -EFAULT;
 
 		err = compat_get_fastrpc_ioctl_mem_map(map32, map);
-		if (err)
+		if (err) {
+			kfree(map);
 			return err;
+		}
 
 		VERIFY(err, 0 == (err = fastrpc_internal_mem_map(fl,
 						map)));
-		if (err)
+		if (err) {
+			kfree(map);
 			return err;
+		}
 		VERIFY(err, 0 == compat_put_fastrpc_ioctl_mem_map(map32, map));
+		kfree(map);
 		return err;
 	}
 	case COMPAT_FASTRPC_IOCTL_MEM_UNMAP:
 	{
 		struct compat_fastrpc_ioctl_mem_unmap __user *unmap32;
-		struct fastrpc_ioctl_mem_unmap *unmap;
+		struct fastrpc_ioctl_mem_unmap *unmap = NULL;
 
 		unmap32 = compat_ptr(arg);
-		unmap = kmalloc(sizeof(*unmap), GFP_KERNEL);
+		unmap = kzalloc(sizeof(*unmap), GFP_KERNEL);
 		if (unmap == NULL)
 			return -EFAULT;
 
 		err = compat_get_fastrpc_ioctl_mem_unmap(unmap32, unmap);
-		if (err)
+		if (err) {
+			kfree(unmap);
 			return err;
+		}
 
 		VERIFY(err, 0 == (err = fastrpc_internal_mem_unmap(fl,
 						unmap)));
+		kfree(unmap);
 		return err;
 	}
 	case COMPAT_FASTRPC_IOCTL_MMAP:
 	{
 		struct compat_fastrpc_ioctl_mmap __user *map32;
-		struct fastrpc_ioctl_mmap *map;
+		struct fastrpc_ioctl_mmap *map = NULL;
 
 		map32 = compat_ptr(arg);
-		VERIFY(err, NULL != (map = kmalloc(
+		VERIFY(err, NULL != (map = kzalloc(
 							sizeof(*map), GFP_KERNEL)));
 		if (err)
 			return -EFAULT;
 		VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap(map32, map));
-		if (err)
+		if (err) {
+			kfree(map);
 			return err;
+		}
 
 		VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, map)));
 
 		VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap(map32, map));
+		kfree(map);
 		return err;
 	}
 	case COMPAT_FASTRPC_IOCTL_MMAP_64:
 	{
 		struct compat_fastrpc_ioctl_mmap_64  __user *map32;
-		struct fastrpc_ioctl_mmap *map;
+		struct fastrpc_ioctl_mmap *map = NULL;
 
 		map32 = compat_ptr(arg);
-		VERIFY(err, NULL != (map = kmalloc(
+		VERIFY(err, NULL != (map = kzalloc(
 							sizeof(*map), GFP_KERNEL)));
 		if (err)
 			return -EFAULT;
 		VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap_64(map32, map));
-		if (err)
+		if (err) {
+			kfree(map);
 			return err;
+		}
 		VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, map)));
 		VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap_64(map32, map));
+		kfree(map);
 		return err;
 	}
 	case COMPAT_FASTRPC_IOCTL_MUNMAP:
 	{
 		struct compat_fastrpc_ioctl_munmap __user *unmap32;
-		struct fastrpc_ioctl_munmap *unmap;
+		struct fastrpc_ioctl_munmap *unmap = NULL;
 
 		unmap32 = compat_ptr(arg);
-		VERIFY(err, NULL != (unmap = kmalloc(
+		VERIFY(err, NULL != (unmap = kzalloc(
 							sizeof(*unmap), GFP_KERNEL)));
 		if (err)
 			return -EFAULT;
 		VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap(unmap32,
 							unmap));
-		if (err)
+		if (err) {
+			kfree(unmap);
 			return err;
+		}
 		VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
 							unmap)));
+		kfree(unmap);
 		return err;
 	}
 	default:
@@ -991,21 +1008,25 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
 	case COMPAT_FASTRPC_IOCTL_MUNMAP_64:
 	{
 		struct compat_fastrpc_ioctl_munmap_64 __user *unmap32;
-		struct fastrpc_ioctl_munmap *unmap;
+		struct fastrpc_ioctl_munmap *unmap = NULL;
 
 		unmap32 = compat_ptr(arg);
-		VERIFY(err, NULL != (unmap = kmalloc(
+		VERIFY(err, NULL != (unmap = kzalloc(
 							sizeof(*unmap), GFP_KERNEL)));
 
 		if (err)
 			return -EFAULT;
 		VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap_64(unmap32,
 							unmap));
-		if (err)
+		if (err) {
+			kfree(unmap);
 			return err;
+		}
 
 		VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
 							unmap)));
+
+		kfree(unmap);
 		return err;
 	}
 	case COMPAT_FASTRPC_IOCTL_INIT:
@@ -1013,40 +1034,46 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
 	case COMPAT_FASTRPC_IOCTL_INIT_ATTRS:
 	{
 		struct compat_fastrpc_ioctl_init_attrs __user *init32;
-		struct fastrpc_ioctl_init_attrs *init;
+		struct fastrpc_ioctl_init_attrs *init = NULL;
 
 		init32 = compat_ptr(arg);
-		VERIFY(err, NULL != (init = kmalloc(
+		VERIFY(err, NULL != (init = kzalloc(
 							sizeof(*init), GFP_KERNEL)));
 		if (err)
 			return -EFAULT;
 		VERIFY(err, 0 == compat_get_fastrpc_ioctl_init(init32,
 							init, cmd));
-		if (err)
+		if (err) {
+			kfree(init);
 			return err;
+		}
 		VERIFY(err, 0 == (err = fastrpc_init_process(fl, init)));
 
+		kfree(init);
 		return err;
 
 	}
 	case FASTRPC_IOCTL_GETINFO:
 	{
 		compat_uptr_t __user *info32;
-		uint32_t *info;
+		uint32_t *info = NULL;
 		compat_uint_t u;
 
 		info32 = compat_ptr(arg);
-		VERIFY(err, NULL != (info = kmalloc(
+		VERIFY(err, NULL != (info = kzalloc(
 							sizeof(*info), GFP_KERNEL)));
 		if (err)
 			return -EFAULT;
 		err = get_user(u, info32);
 		memcpy(info, &u, sizeof(u));
-		if (err)
+		if (err) {
+			kfree(info);
 			return err;
+		}
 		VERIFY(err, 0 == (err = fastrpc_get_info(fl, info)));
 		memcpy(&u, info, sizeof(*info));
 		err |= put_user(u, info32);
+		kfree(info);
 		return err;
 	}
 	case FASTRPC_IOCTL_SETMODE:

+ 2 - 0
dsp/adsprpc_shared.h

@@ -794,6 +794,8 @@ struct fastrpc_mmap {
 	char *servloc_name;			/* Indicate which daemon mapped this */
 	/* Indicates map is being used by a pending RPC call */
 	unsigned int ctx_refs;
+	/* Map in use for dma handle */
+	unsigned int dma_handle_refs;
 };
 
 enum fastrpc_perfkeys {