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

Commit d996b26e authored by Tharun Kumar Merugu's avatar Tharun Kumar Merugu
Browse files

msm: adsprpc: DSP device node to provide restricted access to ADSP/SLPI



Support 2 separate device nodes with this change, one for ADSP/SLPI
and another for CDSP.

Change-Id: I2a09ebfdeccd9a092b1a3602c249b2727ec91c92
Acked-by: default avatarAmol Mahesh <amahesh@qti.qualcomm.com>
Signed-off-by: default avatarTharun Kumar Merugu <mtharu@codeaurora.org>
parent 7d7c5b26
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ Optional properties:
- qcom,adsp-remoteheap-vmid:  FastRPC remote heap VMID list
- qcom,fastrpc-adsp-audio-pdr:  Flag to enable ADSP Audio PDR
- qcom,fastrpc-adsp-sensors-pdr: Flag to enable Sensors PDR
- qcom,secure-domains:  FastRPC secure domain configuration

Optional subnodes:
- qcom,msm_fastrpc_compute_cb :	Child nodes representing the compute context
+118 −7
Original line number Diff line number Diff line
@@ -79,6 +79,16 @@
#define FASTRPC_CTX_MAGIC (0xbeeddeed)
#define FASTRPC_CTX_MAX (256)
#define FASTRPC_CTXID_MASK (0xFF0)
#define NUM_DEVICES   2 /* adsprpc-smd, adsprpc-smd-secure */
#define MINOR_NUM_DEV 0
#define MINOR_NUM_SECURE_DEV 1
#define NON_SECURE_CHANNEL 0
#define SECURE_CHANNEL 1

#define ADSP_DOMAIN_ID (0)
#define MDSP_DOMAIN_ID (1)
#define SDSP_DOMAIN_ID (2)
#define CDSP_DOMAIN_ID (3)

#define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0)

@@ -282,6 +292,8 @@ struct fastrpc_channel_ctx {
	int ramdumpenabled;
	void *remoteheap_ramdump_dev;
	struct fastrpc_glink_info link;
	/* Indicates, if channel is restricted to secure node only */
	int secure;
};

struct fastrpc_apps {
@@ -380,6 +392,8 @@ struct fastrpc_file {
	struct mutex map_mutex;
	struct mutex fl_map_mutex;
	int refcount;
	/* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */
	int dev_minor;
};

static struct fastrpc_apps gfa;
@@ -1854,7 +1868,11 @@ static void fastrpc_init(struct fastrpc_apps *me)
		init_completion(&me->channel[i].work);
		init_completion(&me->channel[i].workport);
		me->channel[i].sesscount = 0;
		/* All channels are secure by default except CDSP */
		me->channel[i].secure = SECURE_CHANNEL;
	}
	/* Set CDSP channel to non secure */
	me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
}

static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl);
@@ -2943,6 +2961,9 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
			len += scnprintf(fileinfo + len,
					DEBUGFS_SIZE - len, "%s\n\n",
					chan->name);
			len += scnprintf(fileinfo + len,
					DEBUGFS_SIZE - len, "%s %d\n",
					"secure:", chan->secure);
			len += scnprintf(fileinfo + len,
					DEBUGFS_SIZE - len, "%s %d\n",
					"sesscount:", chan->sesscount);
@@ -2971,6 +2992,9 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
		len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
				"%s %d\n\n",
				"SSRCOUNT:", fl->ssrcount);
		len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
				"%s %d\n\n",
				"DEV_MINOR:", fl->dev_minor);
		len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
				"%s\n",
				"LIST OF BUFS:");
@@ -3107,6 +3131,19 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
	struct fastrpc_file *fl = NULL;
	struct fastrpc_apps *me = &gfa;

	/*
	 * Indicates the device node opened
	 * MINOR_NUM_DEV or MINOR_NUM_SECURE_DEV
	 */
	int dev_minor = MINOR(inode->i_rdev);

	VERIFY(err, ((dev_minor == MINOR_NUM_DEV) ||
			(dev_minor == MINOR_NUM_SECURE_DEV)));
	if (err) {
		pr_err("adsprpc: Invalid dev minor num %d\n", dev_minor);
		return err;
	}

	VERIFY(err, NULL != (fl = kzalloc(sizeof(*fl), GFP_KERNEL)));
	if (err)
		return err;
@@ -3123,6 +3160,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
	fl->apps = me;
	fl->mode = FASTRPC_MODE_SERIAL;
	fl->cid = -1;
	fl->dev_minor = dev_minor;

	if (debugfs_file != NULL)
		fl->debugfs_file = debugfs_file;
	fl->qos_request = 0;
@@ -3150,6 +3189,23 @@ static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
		VERIFY(err, cid < NUM_CHANNELS);
		if (err)
			goto bail;
		/* Check to see if the device node is non-secure */
		if (fl->dev_minor == MINOR_NUM_DEV) {
			/*
			 * For non secure device node check and make sure that
			 * the channel allows non-secure access
			 * If not, bail. Session will not start.
			 * cid will remain -1 and client will not be able to
			 * invoke any other methods without failure
			 */
			if (fl->apps->channel[cid].secure == SECURE_CHANNEL) {
				err = -EPERM;
				pr_err("adsprpc: GetInfo failed dev %d, cid %d, secure %d\n",
				  fl->dev_minor, cid,
					fl->apps->channel[cid].secure);
				goto bail;
			}
		}
		fl->cid = cid;
		fl->ssrcount = fl->apps->channel[cid].ssrcount;
		VERIFY(err, !fastrpc_session_alloc_locked(
@@ -3721,6 +3777,25 @@ static void init_secure_vmid_list(struct device *dev, char *prop_name,
	}
}

static void configure_secure_channels(uint32_t secure_domains)
{
	struct fastrpc_apps *me = &gfa;
	int ii = 0;
	/*
	 * secure_domains contains the bitmask of the secure channels
	 *  Bit 0 - ADSP
	 *  Bit 1 - MDSP
	 *  Bit 2 - SLPI
	 *  Bit 3 - CDSP
	 */
	for (ii = ADSP_DOMAIN_ID; ii <= CDSP_DOMAIN_ID; ++ii) {
		int secure = (secure_domains >> ii) & 0x01;

		me->channel[ii].secure = secure;
	}
}


static int fastrpc_probe(struct platform_device *pdev)
{
	int err = 0;
@@ -3731,7 +3806,7 @@ static int fastrpc_probe(struct platform_device *pdev)
	struct cma *cma;
	uint32_t val;
	int ret = 0;

	uint32_t secure_domains;

	if (of_device_is_compatible(dev->of_node,
					"qcom,msm-fastrpc-compute")) {
@@ -3741,6 +3816,16 @@ static int fastrpc_probe(struct platform_device *pdev)

		of_property_read_u32(dev->of_node, "qcom,rpc-latency-us",
			&me->latency);
		if (of_get_property(dev->of_node,
			"qcom,secure-domains", NULL) != NULL) {
			VERIFY(err, !of_property_read_u32(dev->of_node,
					  "qcom,secure-domains",
			      &secure_domains));
			if (!err)
				configure_secure_channels(secure_domains);
			else
				pr_info("adsprpc: unable to read the domain configuration from dts\n");
		}
	}
	if (of_device_is_compatible(dev->of_node,
					"qcom,msm-fastrpc-compute-cb"))
@@ -3886,6 +3971,7 @@ static int __init fastrpc_device_init(void)
{
	struct fastrpc_apps *me = &gfa;
	struct device *dev = NULL;
	struct device *secure_dev = NULL;
	int err = 0, i;

	memset(me, 0, sizeof(*me));
@@ -3903,7 +3989,7 @@ static int __init fastrpc_device_init(void)
	cdev_init(&me->cdev, &fops);
	me->cdev.owner = THIS_MODULE;
	VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0),
				1));
				NUM_DEVICES));
	if (err)
		goto cdev_init_bail;
	me->class = class_create(THIS_MODULE, "fastrpc");
@@ -3911,13 +3997,29 @@ static int __init fastrpc_device_init(void)
	if (err)
		goto class_create_bail;
	me->compat = (fops.compat_ioctl == NULL) ? 0 : 1;

	/*
	 * Create devices and register with sysfs
	 * Create first device with minor number 0
	 */
	dev = device_create(me->class, NULL,
				MKDEV(MAJOR(me->dev_no), 0),
				NULL, gcinfo[0].name);
				MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV),
				NULL, DEVICE_NAME);
	VERIFY(err, !IS_ERR_OR_NULL(dev));
	if (err)
		goto device_create_bail;

	/* Create secure device with minor number for secure device */
	secure_dev = device_create(me->class, NULL,
				MKDEV(MAJOR(me->dev_no), MINOR_NUM_SECURE_DEV),
				NULL, DEVICE_NAME_SECURE);
	VERIFY(err, !IS_ERR_OR_NULL(secure_dev));
	if (err)
		goto device_create_bail;

	for (i = 0; i < NUM_CHANNELS; i++) {
		me->channel[i].dev = secure_dev;
		if (i == CDSP_DOMAIN_ID)
			me->channel[i].dev = dev;
		me->channel[i].ssrcount = 0;
		me->channel[i].prevssrcount = 0;
@@ -3943,7 +4045,11 @@ static int __init fastrpc_device_init(void)
							&me->channel[i].nb);
	}
	if (!IS_ERR_OR_NULL(dev))
		device_destroy(me->class, MKDEV(MAJOR(me->dev_no), 0));
		device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
						MINOR_NUM_DEV));
	if (!IS_ERR_OR_NULL(secure_dev))
		device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
						 MINOR_NUM_SECURE_DEV));
	class_destroy(me->class);
class_create_bail:
	cdev_del(&me->cdev);
@@ -3965,10 +4071,15 @@ static void __exit fastrpc_device_exit(void)
	for (i = 0; i < NUM_CHANNELS; i++) {
		if (!gcinfo[i].name)
			continue;
		device_destroy(me->class, MKDEV(MAJOR(me->dev_no), i));
		subsys_notif_unregister_notifier(me->channel[i].handle,
						&me->channel[i].nb);
	}

	/* Destroy the secure and non secure devices */
	device_destroy(me->class, MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV));
	device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
					 MINOR_NUM_SECURE_DEV));

	class_destroy(me->class);
	cdev_del(&me->cdev);
	unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
#define DEVICE_NAME      "adsprpc-smd"
#define DEVICE_NAME_SECURE "adsprpc-smd-secure"

/* Set for buffers that have no virtual mapping in userspace */
#define FASTRPC_ATTR_NOVA 0x1