diff options
Diffstat (limited to 'drivers/misc/fastrpc.c')
| -rw-r--r-- | drivers/misc/fastrpc.c | 31 | 
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index f48466960f1b..30d4d0476248 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -316,12 +316,14 @@ static void fastrpc_free_map(struct kref *ref)  	if (map->table) {  		if (map->attr & FASTRPC_ATTR_SECUREMAP) {  			struct qcom_scm_vmperm perm; +			int vmid = map->fl->cctx->vmperms[0].vmid; +			u64 src_perms = BIT(QCOM_SCM_VMID_HLOS) | BIT(vmid);  			int err = 0;  			perm.vmid = QCOM_SCM_VMID_HLOS;  			perm.perm = QCOM_SCM_PERM_RWX;  			err = qcom_scm_assign_mem(map->phys, map->size, -				&map->fl->cctx->perms, &perm, 1); +				&src_perms, &perm, 1);  			if (err) {  				dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d",  						map->phys, map->size, err); @@ -787,8 +789,12 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,  		goto map_err;  	} -	map->phys = sg_dma_address(map->table->sgl); -	map->phys += ((u64)fl->sctx->sid << 32); +	if (attr & FASTRPC_ATTR_SECUREMAP) { +		map->phys = sg_phys(map->table->sgl); +	} else { +		map->phys = sg_dma_address(map->table->sgl); +		map->phys += ((u64)fl->sctx->sid << 32); +	}  	map->size = len;  	map->va = sg_virt(map->table->sgl);  	map->len = len; @@ -798,9 +804,15 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,  		 * If subsystem VMIDs are defined in DTSI, then do  		 * hyp_assign from HLOS to those VM(s)  		 */ +		u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); +		struct qcom_scm_vmperm dst_perms[2] = {0}; + +		dst_perms[0].vmid = QCOM_SCM_VMID_HLOS; +		dst_perms[0].perm = QCOM_SCM_PERM_RW; +		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, &fl->cctx->perms, -				fl->cctx->vmperms, fl->cctx->vmcount); +		err = qcom_scm_assign_mem(map->phys, (u64)map->size, &src_perms, dst_perms, 2);  		if (err) {  			dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d",  					map->phys, map->size, err); @@ -1892,7 +1904,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)  	req.vaddrout = rsp_msg.vaddr;  	/* Add memory to static PD pool, protection thru hypervisor */ -	if (req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { +	if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) {  		struct qcom_scm_vmperm perm;  		perm.vmid = QCOM_SCM_VMID_HLOS; @@ -2337,8 +2349,10 @@ static void fastrpc_notify_users(struct fastrpc_user *user)  	struct fastrpc_invoke_ctx *ctx;  	spin_lock(&user->lock); -	list_for_each_entry(ctx, &user->pending, node) +	list_for_each_entry(ctx, &user->pending, node) { +		ctx->retval = -EPIPE;  		complete(&ctx->work); +	}  	spin_unlock(&user->lock);  } @@ -2349,7 +2363,9 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)  	struct fastrpc_user *user;  	unsigned long flags; +	/* No invocations past this point */  	spin_lock_irqsave(&cctx->lock, flags); +	cctx->rpdev = NULL;  	list_for_each_entry(user, &cctx->users, user)  		fastrpc_notify_users(user);  	spin_unlock_irqrestore(&cctx->lock, flags); @@ -2368,7 +2384,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)  	of_platform_depopulate(&rpdev->dev); -	cctx->rpdev = NULL;  	fastrpc_channel_ctx_put(cctx);  }  | 
