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

Commit cb770397 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: adsprpc: API to get DSP capability"

parents 4ec486b4 ebe00203
Loading
Loading
Loading
Loading
+161 −15
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
#include <linux/completion.h>
#include <linux/pagemap.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/cdev.h>
@@ -32,7 +31,6 @@
#include <soc/qcom/service-notifier.h>
#include <soc/qcom/service-locator.h>
#include <linux/scatterlist.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/of.h>
@@ -51,6 +49,8 @@
#include <soc/qcom/ramdump.h>
#include <linux/debugfs.h>
#include <linux/pm_qos.h>
#include <linux/stat.h>

#define TZ_PIL_PROTECT_MEM_SUBSYS_ID 0x0C
#define TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID 0x0D
#define TZ_PIL_AUTH_QDSP6_PROC 1
@@ -106,8 +106,9 @@
#define FASTRPC_GLINK_INTENT_NUM  (16)

#define PERF_KEYS \
	"count:flush:map:copy:glink:getargs:putargs:invalidate:invoke:tid:ptr"
#define FASTRPC_STATIC_HANDLE_KERNEL (1)
	"count:flush:map:copy:rpmsg:getargs:putargs:invalidate:invoke:tid:ptr"
#define FASTRPC_STATIC_HANDLE_PROCESS_GROUP (1)
#define FASTRPC_STATIC_HANDLE_DSP_UTILITIES (2)
#define FASTRPC_STATIC_HANDLE_LISTENER (3)
#define FASTRPC_STATIC_HANDLE_MAX (20)
#define FASTRPC_LATENCY_CTRL_ENB  (1)
@@ -285,6 +286,11 @@ struct fastrpc_glink_info {
	void *link_notify_handle;
};

struct fastrpc_dsp_capabilities {
	uint32_t is_cached;	//! Flag if dsp attributes are cached
	uint32_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
};

struct fastrpc_channel_ctx {
	char *name;
	char *subsys;
@@ -309,6 +315,7 @@ struct fastrpc_channel_ctx {
	struct fastrpc_glink_info link;
	/* Indicates, if channel is restricted to secure node only */
	int secure;
	struct fastrpc_dsp_capabilities dsp_cap_kernel;
};

struct fastrpc_apps {
@@ -2066,10 +2073,13 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
		getnstimeofday(&invoket);

	if (!kernel) {
		VERIFY(err, invoke->handle != FASTRPC_STATIC_HANDLE_KERNEL);
		VERIFY(err, invoke->handle !=
			FASTRPC_STATIC_HANDLE_PROCESS_GROUP);
		VERIFY(err, invoke->handle !=
			FASTRPC_STATIC_HANDLE_DSP_UTILITIES);
		if (err) {
			pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d",
				__func__, current->comm, cid);
			pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d, handle 0x%x\n",
				__func__, current->comm, cid, invoke->handle);
			goto bail;
		}
	}
@@ -2204,7 +2214,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,

		ra[0].buf.pv = (void *)&tgid;
		ra[0].buf.len = sizeof(tgid);
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
		ioctl.inv.pra = ra;
		ioctl.fds = NULL;
@@ -2299,7 +2309,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
		ra[5].buf.len = sizeof(inbuf.siglen);
		fds[5] = 0;

		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0);
		if (uproc->attrs)
			ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0);
@@ -2385,7 +2395,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
		ra[2].buf.pv = (void *)pages;
		ra[2].buf.len = sizeof(*pages);
		fds[2] = 0;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;

		ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
		ioctl.inv.pra = ra;
@@ -2421,6 +2431,119 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
	return err;
}

static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl,
				uint32_t *dsp_attr, uint32_t dsp_attr_size,
				uint32_t domain)
{
	int err = 0, dsp_cap_buff_size, dsp_support = 0;
	struct fastrpc_ioctl_invoke_crc ioctl;
	remote_arg_t ra[2];
	struct fastrpc_apps *me = &gfa;

	// Querying device about DSP support
	switch (domain) {
	case ADSP_DOMAIN_ID:
	case SDSP_DOMAIN_ID:
	case CDSP_DOMAIN_ID:
		if (me->channel[domain].issubsystemup)
			dsp_support = 1;
		break;
	case MDSP_DOMAIN_ID:
		//Modem not supported for fastRPC
		break;
	default:
		dsp_support = 0;
		break;
	}
	dsp_attr[0] = dsp_support;

	if (dsp_support == 0) {
		err = -ENOTCONN;
		goto bail;
	}

	err = fastrpc_channel_open(fl);
	if (err)
		goto bail;

	dsp_cap_buff_size = dsp_attr_size - sizeof(uint32_t);
	ra[0].buf.pv = (void *)&dsp_cap_buff_size;
	ra[0].buf.len = sizeof(dsp_cap_buff_size);
	ra[1].buf.pv = (void *)(&dsp_attr[1]);
	ra[1].buf.len = dsp_cap_buff_size * sizeof(uint32_t);
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_DSP_UTILITIES;
	ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 1);
	ioctl.inv.pra = ra;
	ioctl.fds = NULL;
	ioctl.attrs = NULL;
	ioctl.crc = NULL;
	fl->pd = 1;

	err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl);
bail:

	if (err)
		pr_err("adsprpc: %s: %s: could not obtain dsp information, err val 0x%x\n",
		current->comm, __func__, err);
	return err;
}

static int fastrpc_get_info_from_kernel(
		struct fastrpc_ioctl_dsp_capabilities *dsp_cap,
		struct fastrpc_file *fl)
{
	int err = 0;
	uint32_t domain_support;
	uint32_t domain = dsp_cap->domain;

	if (!gcinfo[domain].dsp_cap_kernel.is_cached) {
		/*
		 * Information not on kernel, query device for information
		 * and cache on kernel
		 */
		err = fastrpc_get_info_from_dsp(fl, dsp_cap->dsp_attributes,
				sizeof(dsp_cap->dsp_attributes),
				domain);
		if (err)
			goto bail;

		domain_support = dsp_cap->dsp_attributes[0];
		switch (domain_support) {
		case 0:
			memset(dsp_cap->dsp_attributes, 0,
				sizeof(dsp_cap->dsp_attributes));
			memset(&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
				0, sizeof(dsp_cap->dsp_attributes));
			break;
		case 1:
			memcpy(&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
				dsp_cap->dsp_attributes,
				sizeof(dsp_cap->dsp_attributes));
			break;
		default:
			err = -1;
			/*
			 * Reset is_cached flag to 0 so subsequent calls
			 * can try to query dsp again
			 */
			gcinfo[domain].dsp_cap_kernel.is_cached = 0;
			pr_warn("adsprpc: %s: %s: returned bad domain support value %d\n",
					current->comm,
					__func__,
					domain_support);
			goto bail;
		}
		gcinfo[domain].dsp_cap_kernel.is_cached = 1;
	} else {
		// Information on Kernel, pass it to user
		memcpy(dsp_cap->dsp_attributes,
			&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
			sizeof(dsp_cap->dsp_attributes));
	}
bail:
	return err;
}

static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
{
	int err = 0;
@@ -2440,7 +2563,7 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
	tgid = fl->tgid;
	ra[0].buf.pv = (void *)&tgid;
	ra[0].buf.len = sizeof(tgid);
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
	ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
	ioctl.inv.pra = ra;
	ioctl.fds = NULL;
@@ -2486,7 +2609,7 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
	ra[2].buf.pv = (void *)&routargs;
	ra[2].buf.len = sizeof(routargs);

	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
	if (fl->apps->compat)
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(4, 2, 1);
	else
@@ -2547,7 +2670,7 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys,
		ra[1].buf.pv = (void *)&routargs;
		ra[1].buf.len = sizeof(routargs);

		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1);
		ioctl.inv.pra = ra;
		ioctl.fds = NULL;
@@ -2609,7 +2732,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, uintptr_t raddr,
	ra[0].buf.pv = (void *)&inargs;
	ra[0].buf.len = sizeof(inargs);

	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
	if (fl->apps->compat)
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(5, 1, 0);
	else
@@ -3739,6 +3862,26 @@ static int fastrpc_internal_control(struct fastrpc_file *fl,
	return err;
}

static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap,
				void *param, struct fastrpc_file *fl)
{
	int err = 0;

	K_COPY_FROM_USER(err, 0, dsp_cap, param,
			sizeof(struct fastrpc_ioctl_dsp_capabilities));
	VERIFY(err, dsp_cap->domain < NUM_CHANNELS);
	if (err)
		goto bail;

	err = fastrpc_get_info_from_kernel(dsp_cap, fl);
	if (err)
		goto bail;
	K_COPY_TO_USER(err, 0, param, dsp_cap,
			sizeof(struct fastrpc_ioctl_dsp_capabilities));
bail:
	return err;
}

static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
				 unsigned long ioctl_param)
{
@@ -3752,6 +3895,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
		struct fastrpc_ioctl_init_attrs init;
		struct fastrpc_ioctl_perf perf;
		struct fastrpc_ioctl_control cp;
		struct fastrpc_ioctl_dsp_capabilities dsp_cap;
	} p;
	union {
		struct fastrpc_ioctl_mmap mmap;
@@ -3962,7 +4106,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
		if (err)
			goto bail;
		break;

	case FASTRPC_IOCTL_GET_DSP_INFO:
		err = fastrpc_get_dsp_info(&p.dsp_cap, param, fl);
		break;
	default:
		err = -ENOTTY;
		pr_info("bad ioctl: %d\n", ioctl_num);
+57 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
 *
 * 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
@@ -43,6 +43,8 @@
		_IOWR('R', 14, struct compat_fastrpc_ioctl_mmap_64)
#define COMPAT_FASTRPC_IOCTL_MUNMAP_64 \
		_IOWR('R', 15, struct compat_fastrpc_ioctl_munmap_64)
#define COMPAT_FASTRPC_IOCTL_GET_DSP_INFO \
		_IOWR('R', 16, struct compat_fastrpc_ioctl_dsp_capabilities)

struct compat_remote_buf {
	compat_uptr_t pv;	/* buffer pointer */
@@ -151,6 +153,11 @@ struct compat_fastrpc_ioctl_control {
	};
};

struct compat_fastrpc_ioctl_dsp_capabilities {
	compat_uint_t domain;	/* DSP domain to query capabilities */
	compat_uint_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
};

static int compat_get_fastrpc_ioctl_invoke(
			struct compat_fastrpc_ioctl_invoke_crc __user *inv32,
			struct fastrpc_ioctl_invoke_crc __user **inva,
@@ -389,6 +396,53 @@ static int compat_get_fastrpc_ioctl_init(
	return err;
}

static int compat_put_fastrpc_ioctl_get_dsp_info(
		struct compat_fastrpc_ioctl_dsp_capabilities __user *info32,
		struct fastrpc_ioctl_dsp_capabilities __user *info)
{
	compat_uint_t u;
	int err, ii;

	for (ii = 0, err = 0; ii < FASTRPC_MAX_DSP_ATTRIBUTES; ii++) {
		err |= get_user(u, &info->dsp_attributes[ii]);
		err |= put_user(u, &info32->dsp_attributes[ii]);
	}

	return err;
}



static int compat_fastrpc_get_dsp_info(struct file *filp,
		unsigned long arg)
{
	struct compat_fastrpc_ioctl_dsp_capabilities __user *info32;
	struct fastrpc_ioctl_dsp_capabilities __user *info;
	compat_uint_t u;
	long ret;
	int err = 0;

	info32 = compat_ptr(arg);
	VERIFY(err, NULL != (info = compat_alloc_user_space(
						sizeof(*info))));
	if (err)
		return -EFAULT;

	err = get_user(u, &info32->domain);
	err |= put_user(u, &info->domain);
	if (err)
		return err;

	ret = filp->f_op->unlocked_ioctl(filp,
			FASTRPC_IOCTL_GET_DSP_INFO,
			(unsigned long)info);
	if (ret)
		return ret;

	err = compat_put_fastrpc_ioctl_get_dsp_info(info32, info);
	return err;
}

long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
@@ -588,6 +642,8 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
		err |= put_user(u, &perf32->numkeys);
		return err;
	}
	case COMPAT_FASTRPC_IOCTL_GET_DSP_INFO:
		return compat_fastrpc_get_dsp_info(filp, arg);
	default:
		return -ENOIOCTLCMD;
	}
+9 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
 *
 * 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
@@ -32,6 +32,8 @@
#define FASTRPC_IOCTL_INVOKE_CRC _IOWR('R', 11, struct fastrpc_ioctl_invoke_crc)
#define FASTRPC_IOCTL_CONTROL   _IOWR('R', 12, struct fastrpc_ioctl_control)
#define FASTRPC_IOCTL_MUNMAP_FD _IOWR('R', 13, struct fastrpc_ioctl_munmap_fd)
#define FASTRPC_IOCTL_GET_DSP_INFO \
			_IOWR('R', 16, struct fastrpc_ioctl_dsp_capabilities)

#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
@@ -269,6 +271,12 @@ struct fastrpc_ioctl_control {
	};
};

#define FASTRPC_MAX_DSP_ATTRIBUTES	(7)
struct fastrpc_ioctl_dsp_capabilities {
	uint32_t domain;	//! DSP domain to query capabilities
	uint32_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
};

struct smq_null_invoke {
	uint64_t ctx;			/* invoke caller context */
	uint32_t handle;	    /* handle to invoke */