Эх сурвалжийг харах

Merge 7fd02f3859012cd24f4a3bbce12055566a599189 on remote branch

Change-Id: I9b926588408013e5dfd871aee12e5d3356da20ba
Linux Build Service Account 1 жил өмнө
parent
commit
b25544b738
2 өөрчлөгдсөн 162 нэмэгдсэн , 31 устгасан
  1. 132 31
      dsp/adsprpc.c
  2. 30 0
      dsp/fastrpc_trace.h

+ 132 - 31
dsp/adsprpc.c

@@ -43,6 +43,7 @@
 #include "adsprpc_shared.h"
 #include "adsprpc_shared.h"
 #include <soc/qcom/qcom_ramdump.h>
 #include <soc/qcom/qcom_ramdump.h>
 #include <soc/qcom/minidump.h>
 #include <soc/qcom/minidump.h>
+#include <soc/qcom/secure_buffer.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/debugfs.h>
 #include <linux/debugfs.h>
 #include <linux/pm_qos.h>
 #include <linux/pm_qos.h>
@@ -1159,6 +1160,77 @@ bail:
 	return err;
 	return err;
 }
 }
 
 
+static int get_buffer_attr(struct dma_buf *buf, bool *exclusive_access, bool *hlos_access)
+{
+	const int *vmids_list = NULL, *perms = NULL;
+	int err = 0, vmids_list_len = 0;
+
+	*exclusive_access = false;
+	*hlos_access = false;
+	err = mem_buf_dma_buf_get_vmperm(buf, &vmids_list, &perms, &vmids_list_len);
+	if (err)
+		goto bail;
+
+	/*
+	 * If one VM has access to buffer and is the current VM,
+	 * then VM has exclusive access to buffer
+	 */
+	if (vmids_list_len == 1 && vmids_list[0] == mem_buf_current_vmid())
+		*exclusive_access = true;
+
+#if IS_ENABLED(CONFIG_MSM_ADSPRPC_TRUSTED)
+	/*
+	 * PVM (HLOS) can share buffers with TVM. In that case,
+	 * it is expected to relinquish its ownership to those buffers
+	 * before sharing. But if the PVM still retains access, then
+	 * these buffers cannot be used by TVM.
+	 */
+
+	for (int ii = 0; ii < vmids_list_len; ii++) {
+		if (vmids_list[ii] == VMID_HLOS) {
+			*hlos_access = true;
+			break;
+		}
+	}
+#endif
+
+bail:
+	return err;
+}
+
+static int set_buffer_secure_type(struct fastrpc_mmap *map)
+{
+	int err = 0;
+	bool hlos_access = false, exclusive_access = false;
+
+	VERIFY(err, 0 == (err = get_buffer_attr(map->buf, &exclusive_access, &hlos_access)));
+	if (err) {
+		ADSPRPC_ERR("failed to obtain buffer attributes for fd %d ret %d\n", map->fd, err);
+		err = -EBADFD;
+		goto bail;
+	}
+#if IS_ENABLED(CONFIG_MSM_ADSPRPC_TRUSTED)
+	if (hlos_access) {
+		ADSPRPC_ERR("Sharing HLOS buffer (fd %d) not allowed on TVM\n", map->fd);
+		err = -EACCES;
+		goto bail;
+	}
+#endif
+	/*
+	 * Secure buffers would always be owned by multiple VMs.
+	 * If current VM is the exclusive owner of a buffer, it is considered non-secure.
+	 * In PVM:
+	 *	- CPZ buffers are secure
+	 *	- All other buffers are non-secure
+	 * In TVM:
+	 *	- Since it is a secure environment by default, there are no explicit "secure" buffers
+	 *	- All buffers are marked "non-secure"
+	 */
+	map->secure = (exclusive_access) ? 0 : 1;
+bail:
+	return err;
+}
+
 static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, struct dma_buf *buf,
 static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, struct dma_buf *buf,
 	unsigned int attr, uintptr_t va, size_t len, int mflags,
 	unsigned int attr, uintptr_t va, size_t len, int mflags,
 	struct fastrpc_mmap **ppmap)
 	struct fastrpc_mmap **ppmap)
@@ -1224,10 +1296,10 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, struct dma_buf *
 			err = -EBADFD;
 			err = -EBADFD;
 			goto bail;
 			goto bail;
 		}
 		}
+		err = set_buffer_secure_type(map);
+		if (err)
+			goto bail;
 
 
-#if !IS_ENABLED(CONFIG_MSM_ADSPRPC_TRUSTED)
-		map->secure = (mem_buf_dma_buf_exclusive_owner(map->buf)) ? 0 : 1;
-#endif
 		map->va = 0;
 		map->va = 0;
 		map->phys = 0;
 		map->phys = 0;
 
 
@@ -1293,10 +1365,10 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, struct dma_buf *
 				goto bail;
 				goto bail;
 			}
 			}
 		}
 		}
+		err = set_buffer_secure_type(map);
+		if (err)
+			goto bail;
 
 
-#if !IS_ENABLED(CONFIG_MSM_ADSPRPC_TRUSTED)
-		map->secure = (mem_buf_dma_buf_exclusive_owner(map->buf)) ? 0 : 1;
-#endif
 		if (map->secure) {
 		if (map->secure) {
 			if (!fl->secsctx)
 			if (!fl->secsctx)
 				err = fastrpc_session_alloc_secure_memory(chan, 1,
 				err = fastrpc_session_alloc_secure_memory(chan, 1,
@@ -2488,6 +2560,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
 			err = -EFAULT;
 			err = -EFAULT;
 			goto bail;
 			goto bail;
 		}
 		}
+		if (templen > DEBUG_PRINT_SIZE_LIMIT)
+			ADSPRPC_WARN(
+				"user passed non ion buffer size %zu, mend 0x%llx mstart 0x%llx, sc 0x%x  handle 0x%x\n",
+				templen, mend, mstart, sc, ctx->handle);
 		copylen += templen;
 		copylen += templen;
 	}
 	}
 	totallen = ALIGN(totallen, BALIGN) + copylen;
 	totallen = ALIGN(totallen, BALIGN) + copylen;
@@ -3943,9 +4019,12 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
 	struct smq_phy_page pages[PAGESLEN_WITH_SHAREDBUF];
 	struct smq_phy_page pages[PAGESLEN_WITH_SHAREDBUF];
 	struct fastrpc_mmap *file = NULL;
 	struct fastrpc_mmap *file = NULL;
 	struct fastrpc_buf *imem = NULL;
 	struct fastrpc_buf *imem = NULL;
-	unsigned long imem_dma_attr = 0;
+	unsigned long imem_dma_attr = 0, irq_flags = 0;
 	remote_arg_t ra[6];
 	remote_arg_t ra[6];
 	int fds[6];
 	int fds[6];
+	struct fastrpc_apps *me = &gfa;
+	struct hlist_node *n = NULL;
+	struct fastrpc_file *fl_curr = NULL;
 	unsigned int gid = 0, one_mb = 1024*1024;
 	unsigned int gid = 0, one_mb = 1024*1024;
 	unsigned int dsp_userpd_memlen = 0;
 	unsigned int dsp_userpd_memlen = 0;
 	struct fastrpc_buf *init_mem;
 	struct fastrpc_buf *init_mem;
@@ -3993,6 +4072,20 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
 	if (uproc->attrs & FASTRPC_MODE_UNSIGNED_MODULE)
 	if (uproc->attrs & FASTRPC_MODE_UNSIGNED_MODULE)
 		fl->is_unsigned_pd = true;
 		fl->is_unsigned_pd = true;
 
 
+	/* Validate that any existing sessions of process are of same pd type */
+	spin_lock_irqsave(&me->hlock, irq_flags);
+	hlist_for_each_entry_safe(fl_curr, n, &me->drivers, hn) {
+		if ((fl != fl_curr) && (fl->tgid == fl_curr->tgid) && (fl->cid == fl_curr->cid)) {
+			err = (fl->is_unsigned_pd != fl_curr->is_unsigned_pd) ? -ECONNREFUSED : 0;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&me->hlock, irq_flags);
+	if (err) {
+		ADSPRPC_ERR("existing session pd type %u not same as requested pd type %u \n",
+			fl_curr->is_unsigned_pd, fl->is_unsigned_pd);
+		goto bail;
+	}
 	/* Check if file memory passed by userspace is valid */
 	/* Check if file memory passed by userspace is valid */
 	VERIFY(err, access_ok((void __user *)init->file, init->filelen));
 	VERIFY(err, access_ok((void __user *)init->file, init->filelen));
 	if (err)
 	if (err)
@@ -5652,6 +5745,7 @@ static void handle_remote_signal(uint64_t msg, int cid)
 				    (sig->state == DSPSIGNAL_STATE_SIGNALED)) {
 				    (sig->state == DSPSIGNAL_STATE_SIGNALED)) {
 					DSPSIGNAL_VERBOSE("Signaling signal %u for PID %u\n",
 					DSPSIGNAL_VERBOSE("Signaling signal %u for PID %u\n",
 							  signal_id, pid);
 							  signal_id, pid);
+					trace_fastrpc_dspsignal("complete", signal_id, sig->state, 0);
 					complete(&sig->comp);
 					complete(&sig->comp);
 					sig->state = DSPSIGNAL_STATE_SIGNALED;
 					sig->state = DSPSIGNAL_STATE_SIGNALED;
 				} else if (sig->state == DSPSIGNAL_STATE_UNUSED) {
 				} else if (sig->state == DSPSIGNAL_STATE_UNUSED) {
@@ -5682,7 +5776,7 @@ int fastrpc_handle_rpc_response(void *data, int len, int cid)
 	struct fastrpc_channel_ctx *chan = NULL;
 	struct fastrpc_channel_ctx *chan = NULL;
 	unsigned long irq_flags = 0;
 	unsigned long irq_flags = 0;
 	int64_t ns = 0;
 	int64_t ns = 0;
-	uint64_t xo_time_in_us = 0;
+	uint64_t xo_time_in_us = 0, dspsig_msg = 0;
 
 
 	xo_time_in_us = CONVERT_CNT_TO_US(__arch_counter_get_cntvct());
 	xo_time_in_us = CONVERT_CNT_TO_US(__arch_counter_get_cntvct());
 
 
@@ -5690,7 +5784,9 @@ int fastrpc_handle_rpc_response(void *data, int len, int cid)
 		/*
 		/*
 		 * dspsignal message from the DSP
 		 * dspsignal message from the DSP
 		 */
 		 */
-		handle_remote_signal(*((uint64_t *)data), cid);
+		dspsig_msg = *((uint64_t *)data);
+		trace_fastrpc_transport_response(cid, dspsig_msg, 0, 0, 0);
+		handle_remote_signal(dspsig_msg, cid);
 		goto bail;
 		goto bail;
 	}
 	}
 
 
@@ -6762,12 +6858,6 @@ int fastrpc_setmode(unsigned long ioctl_param,
 		fl->profile = (uint32_t)ioctl_param;
 		fl->profile = (uint32_t)ioctl_param;
 		break;
 		break;
 	case FASTRPC_MODE_SESSION:
 	case FASTRPC_MODE_SESSION:
-		if (fl->untrusted_process) {
-			err = -EPERM;
-			ADSPRPC_ERR(
-				"multiple sessions not allowed for untrusted apps\n");
-			goto bail;
-		}
 		if (!fl->multi_session_support)
 		if (!fl->multi_session_support)
 			fl->sessionid = 1;
 			fl->sessionid = 1;
 		break;
 		break;
@@ -6775,7 +6865,6 @@ int fastrpc_setmode(unsigned long ioctl_param,
 		err = -ENOTTY;
 		err = -ENOTTY;
 		break;
 		break;
 	}
 	}
-bail:
 	return err;
 	return err;
 }
 }
 
 
@@ -6870,7 +6959,7 @@ int fastrpc_dspsignal_signal(struct fastrpc_file *fl,
 	msg = (((uint64_t)fl->tgid_frpc) << 32) | ((uint64_t)sig->signal_id);
 	msg = (((uint64_t)fl->tgid_frpc) << 32) | ((uint64_t)sig->signal_id);
 	err = fastrpc_transport_send(cid, (void *)&msg, sizeof(msg), fl->tvm_remote_domain);
 	err = fastrpc_transport_send(cid, (void *)&msg, sizeof(msg), fl->tvm_remote_domain);
 	mutex_unlock(&channel_ctx->smd_mutex);
 	mutex_unlock(&channel_ctx->smd_mutex);
-
+	trace_fastrpc_dspsignal("signal", sig->signal_id, 0, 0);
 bail:
 bail:
 	return err;
 	return err;
 }
 }
@@ -6923,10 +7012,12 @@ int fastrpc_dspsignal_wait(struct fastrpc_file *fl,
 	}
 	}
 	spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags);
 	spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags);
 
 
+	trace_fastrpc_dspsignal("wait", signal_id, s->state, wait->timeout_usec);
 	if (timeout != 0xffffffff)
 	if (timeout != 0xffffffff)
 		ret = wait_for_completion_interruptible_timeout(&s->comp, timeout);
 		ret = wait_for_completion_interruptible_timeout(&s->comp, timeout);
 	else
 	else
 		ret = wait_for_completion_interruptible(&s->comp);
 		ret = wait_for_completion_interruptible(&s->comp);
+	trace_fastrpc_dspsignal("wakeup", signal_id, s->state, wait->timeout_usec);
 
 
 	if (ret == 0) {
 	if (ret == 0) {
 		DSPSIGNAL_VERBOSE("Wait for signal %u timed out\n", signal_id);
 		DSPSIGNAL_VERBOSE("Wait for signal %u timed out\n", signal_id);
@@ -7114,6 +7205,7 @@ int fastrpc_dspsignal_cancel_wait(struct fastrpc_file *fl,
 
 
 	if (s->state != DSPSIGNAL_STATE_CANCELED) {
 	if (s->state != DSPSIGNAL_STATE_CANCELED) {
 		s->state = DSPSIGNAL_STATE_CANCELED;
 		s->state = DSPSIGNAL_STATE_CANCELED;
+		trace_fastrpc_dspsignal("cancel", signal_id, s->state, 0);
 		complete_all(&s->comp);
 		complete_all(&s->comp);
 	}
 	}
 
 
@@ -8828,7 +8920,12 @@ static int __init fastrpc_device_init(void)
 	VERIFY(err, !IS_ERR(me->class));
 	VERIFY(err, !IS_ERR(me->class));
 	if (err)
 	if (err)
 		goto class_create_bail;
 		goto class_create_bail;
+
+#if IS_ENABLED(CONFIG_MSM_ADSPRPC_TRUSTED)
+	me->compat = 1;
+#else
 	me->compat = (fops.compat_ioctl == NULL) ? 0 : 1;
 	me->compat = (fops.compat_ioctl == NULL) ? 0 : 1;
+#endif
 
 
 	/*
 	/*
 	 * Create devices and register with sysfs
 	 * Create devices and register with sysfs
@@ -8866,29 +8963,33 @@ static int __init fastrpc_device_init(void)
 		if (i == CDSP_DOMAIN_ID) {
 		if (i == CDSP_DOMAIN_ID) {
 			me->channel[i].dev = me->non_secure_dev;
 			me->channel[i].dev = me->non_secure_dev;
 #if !IS_ENABLED(CONFIG_MSM_ADSPRPC_TRUSTED)
 #if !IS_ENABLED(CONFIG_MSM_ADSPRPC_TRUSTED)
+			/*
+			 * Allocate CMA memory for mini dump.
+			 * Ignore error as CMA node may not be available on all targets.
+			 */
 			err = fastrpc_alloc_cma_memory(&region_phys,
 			err = fastrpc_alloc_cma_memory(&region_phys,
 								&region_vaddr,
 								&region_vaddr,
 								MINI_DUMP_DBG_SIZE,
 								MINI_DUMP_DBG_SIZE,
 								(unsigned long)attr);
 								(unsigned long)attr);
 #endif
 #endif
-			if (err)
-				ADSPRPC_WARN("%s: CMA alloc failed  err 0x%x\n",
-						__func__, err);
+			if (err) {
+				ADSPRPC_WARN("CMA alloc failed err 0x%x\n", err);
+				err = 0;
+			}
 			VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
 			VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
 			if (err) {
 			if (err) {
 				err = -ENOMEM;
 				err = -ENOMEM;
-				ADSPRPC_ERR("%s: CMA alloc failed  err 0x%x\n",
-							__func__, err);
-				goto device_create_bail;
+				ADSPRPC_WARN("kzalloc failed err 0x%x\n", err);
+				err = 0;
+			} else {
+				INIT_HLIST_NODE(&buf->hn);
+				buf->virt = region_vaddr;
+				buf->phys = (uintptr_t)region_phys;
+				buf->size = MINI_DUMP_DBG_SIZE;
+				buf->dma_attr = attr;
+				buf->raddr = 0;
+				me->channel[i].buf = buf;
 			}
 			}
-			INIT_HLIST_NODE(&buf->hn);
-			buf->virt = region_vaddr;
-			buf->phys = (uintptr_t)region_phys;
-			buf->size = MINI_DUMP_DBG_SIZE;
-			buf->dma_attr = attr;
-			buf->raddr = 0;
-			ktime_get_real_ts64(&buf->buf_start_time);
-			me->channel[i].buf = buf;
 		}
 		}
 		if (IS_ERR_OR_NULL(me->channel[i].handle))
 		if (IS_ERR_OR_NULL(me->channel[i].handle))
 			pr_warn("adsprpc: %s: SSR notifier register failed for %s with err %d\n",
 			pr_warn("adsprpc: %s: SSR notifier register failed for %s with err %d\n",

+ 30 - 0
dsp/fastrpc_trace.h

@@ -391,6 +391,36 @@ TRACE_EVENT(fastrpc_msg,
 	TP_printk(" %s", __get_str(buf))
 	TP_printk(" %s", __get_str(buf))
 );
 );
 
 
+TRACE_EVENT(fastrpc_dspsignal,
+
+	TP_PROTO(const char *event, uint32_t signal_id,
+		int state, uint32_t timeout),
+
+	TP_ARGS(event, signal_id, state, timeout),
+
+	TP_STRUCT__entry(
+		__string(buf, event)
+		__field(u32, signal_id)
+		__field(int, state)
+		__field(u32, timeout)
+	),
+
+	TP_fast_assign(
+#if IS_ENABLED(CONFIG_MSM_ADSPRPC_TRUSTED)
+		memcpy(__get_str(buf), (event), (sizeof(event) - 1));
+		__get_str(buf)[sizeof(event) - 1] = '\0';
+#else
+		__assign_str(buf, event);
+#endif
+		__entry->signal_id = signal_id;
+		__entry->state = state;
+		__entry->timeout = timeout;
+	),
+
+	TP_printk("%s for sig id %u, state %d, timeout %u",
+		__get_str(buf), __entry->signal_id, __entry->state, __entry->timeout)
+);
+
 #endif
 #endif
 
 
 /* This part must be outside protection */
 /* This part must be outside protection */