mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	misc: fastrpc: Add support for create remote init process
This patch adds support to create or attach remote shell process. The shell process called fastrpc_shell_0 is usually loaded on the DSP when a user process is spawned. Most of the work is derived from various downstream Qualcomm kernels. Credits to various Qualcomm authors who have contributed to this code. Specially Tharun Kumar Merugu <mtharu@codeaurora.org> Co-developed-by: Thierry Escande <thierry.escande@linaro.org> Signed-off-by: Thierry Escande <thierry.escande@linaro.org> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									c68cfb718c
								
							
						
					
					
						commit
						d73f71c7c6
					
				
					 2 changed files with 166 additions and 0 deletions
				
			
		| 
						 | 
					@ -29,7 +29,10 @@
 | 
				
			||||||
#define FASTRPC_MAX_CRCLIST	64
 | 
					#define FASTRPC_MAX_CRCLIST	64
 | 
				
			||||||
#define FASTRPC_PHYS(p)	((p) & 0xffffffff)
 | 
					#define FASTRPC_PHYS(p)	((p) & 0xffffffff)
 | 
				
			||||||
#define FASTRPC_CTX_MAX (256)
 | 
					#define FASTRPC_CTX_MAX (256)
 | 
				
			||||||
 | 
					#define FASTRPC_INIT_HANDLE	1
 | 
				
			||||||
#define FASTRPC_CTXID_MASK (0xFF0)
 | 
					#define FASTRPC_CTXID_MASK (0xFF0)
 | 
				
			||||||
 | 
					#define INIT_FILELEN_MAX (2 * 1024 * 1024)
 | 
				
			||||||
 | 
					#define INIT_MEMLEN_MAX  (8 * 1024 * 1024)
 | 
				
			||||||
#define FASTRPC_DEVICE_NAME	"fastrpc"
 | 
					#define FASTRPC_DEVICE_NAME	"fastrpc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Retrives number of input buffers from the scalars parameter */
 | 
					/* Retrives number of input buffers from the scalars parameter */
 | 
				
			||||||
| 
						 | 
					@ -59,6 +62,14 @@
 | 
				
			||||||
#define FASTRPC_SCALARS(method, in, out) \
 | 
					#define FASTRPC_SCALARS(method, in, out) \
 | 
				
			||||||
		FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0)
 | 
							FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FASTRPC_CREATE_PROCESS_NARGS	6
 | 
				
			||||||
 | 
					/* Remote Method id table */
 | 
				
			||||||
 | 
					#define FASTRPC_RMID_INIT_ATTACH	0
 | 
				
			||||||
 | 
					#define FASTRPC_RMID_INIT_RELEASE	1
 | 
				
			||||||
 | 
					#define FASTRPC_RMID_INIT_CREATE	6
 | 
				
			||||||
 | 
					#define FASTRPC_RMID_INIT_CREATE_ATTR	7
 | 
				
			||||||
 | 
					#define FASTRPC_RMID_INIT_CREATE_STATIC	8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define miscdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, miscdev)
 | 
					#define miscdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, miscdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp",
 | 
					static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp",
 | 
				
			||||||
| 
						 | 
					@ -688,6 +699,109 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl,  u32 kernel,
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int fastrpc_init_create_process(struct fastrpc_user *fl,
 | 
				
			||||||
 | 
										char __user *argp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fastrpc_init_create init;
 | 
				
			||||||
 | 
						struct fastrpc_invoke_args *args;
 | 
				
			||||||
 | 
						struct fastrpc_phy_page pages[1];
 | 
				
			||||||
 | 
						struct fastrpc_map *map = NULL;
 | 
				
			||||||
 | 
						struct fastrpc_buf *imem = NULL;
 | 
				
			||||||
 | 
						int memlen;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							int pgid;
 | 
				
			||||||
 | 
							u32 namelen;
 | 
				
			||||||
 | 
							u32 filelen;
 | 
				
			||||||
 | 
							u32 pageslen;
 | 
				
			||||||
 | 
							u32 attrs;
 | 
				
			||||||
 | 
							u32 siglen;
 | 
				
			||||||
 | 
						} inbuf;
 | 
				
			||||||
 | 
						u32 sc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args = kcalloc(FASTRPC_CREATE_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!args)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (copy_from_user(&init, argp, sizeof(init))) {
 | 
				
			||||||
 | 
							err = -EFAULT;
 | 
				
			||||||
 | 
							goto bail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (init.filelen > INIT_FILELEN_MAX) {
 | 
				
			||||||
 | 
							err = -EINVAL;
 | 
				
			||||||
 | 
							goto bail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inbuf.pgid = fl->tgid;
 | 
				
			||||||
 | 
						inbuf.namelen = strlen(current->comm) + 1;
 | 
				
			||||||
 | 
						inbuf.filelen = init.filelen;
 | 
				
			||||||
 | 
						inbuf.pageslen = 1;
 | 
				
			||||||
 | 
						inbuf.attrs = init.attrs;
 | 
				
			||||||
 | 
						inbuf.siglen = init.siglen;
 | 
				
			||||||
 | 
						fl->pd = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (init.filelen && init.filefd) {
 | 
				
			||||||
 | 
							err = fastrpc_map_create(fl, init.filefd, init.filelen, &map);
 | 
				
			||||||
 | 
							if (err)
 | 
				
			||||||
 | 
								goto bail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memlen = ALIGN(max(INIT_FILELEN_MAX, (int)init.filelen * 4),
 | 
				
			||||||
 | 
							       1024 * 1024);
 | 
				
			||||||
 | 
						err = fastrpc_buf_alloc(fl, fl->sctx->dev, memlen,
 | 
				
			||||||
 | 
									&imem);
 | 
				
			||||||
 | 
						if (err) {
 | 
				
			||||||
 | 
							fastrpc_map_put(map);
 | 
				
			||||||
 | 
							goto bail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fl->init_mem = imem;
 | 
				
			||||||
 | 
						args[0].ptr = (u64)(uintptr_t)&inbuf;
 | 
				
			||||||
 | 
						args[0].length = sizeof(inbuf);
 | 
				
			||||||
 | 
						args[0].fd = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args[1].ptr = (u64)(uintptr_t)current->comm;
 | 
				
			||||||
 | 
						args[1].length = inbuf.namelen;
 | 
				
			||||||
 | 
						args[1].fd = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args[2].ptr = (u64) init.file;
 | 
				
			||||||
 | 
						args[2].length = inbuf.filelen;
 | 
				
			||||||
 | 
						args[2].fd = init.filefd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pages[0].addr = imem->phys;
 | 
				
			||||||
 | 
						pages[0].size = imem->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args[3].ptr = (u64)(uintptr_t) pages;
 | 
				
			||||||
 | 
						args[3].length = 1 * sizeof(*pages);
 | 
				
			||||||
 | 
						args[3].fd = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args[4].ptr = (u64)(uintptr_t)&inbuf.attrs;
 | 
				
			||||||
 | 
						args[4].length = sizeof(inbuf.attrs);
 | 
				
			||||||
 | 
						args[4].fd = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args[5].ptr = (u64)(uintptr_t) &inbuf.siglen;
 | 
				
			||||||
 | 
						args[5].length = sizeof(inbuf.siglen);
 | 
				
			||||||
 | 
						args[5].fd = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0);
 | 
				
			||||||
 | 
						if (init.attrs)
 | 
				
			||||||
 | 
							sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
 | 
				
			||||||
 | 
									      sc, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (err) {
 | 
				
			||||||
 | 
							fastrpc_map_put(map);
 | 
				
			||||||
 | 
							fastrpc_buf_free(imem);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bail:
 | 
				
			||||||
 | 
						kfree(args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct fastrpc_session_ctx *fastrpc_session_alloc(
 | 
					static struct fastrpc_session_ctx *fastrpc_session_alloc(
 | 
				
			||||||
					struct fastrpc_channel_ctx *cctx)
 | 
										struct fastrpc_channel_ctx *cctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -715,6 +829,23 @@ static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx,
 | 
				
			||||||
	spin_unlock(&cctx->lock);
 | 
						spin_unlock(&cctx->lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fastrpc_invoke_args args[1];
 | 
				
			||||||
 | 
						int tgid = 0;
 | 
				
			||||||
 | 
						u32 sc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tgid = fl->tgid;
 | 
				
			||||||
 | 
						args[0].ptr = (u64)(uintptr_t) &tgid;
 | 
				
			||||||
 | 
						args[0].length = sizeof(tgid);
 | 
				
			||||||
 | 
						args[0].fd = -1;
 | 
				
			||||||
 | 
						args[0].reserved = 0;
 | 
				
			||||||
 | 
						sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
 | 
				
			||||||
 | 
									       sc, &args[0]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fastrpc_device_release(struct inode *inode, struct file *file)
 | 
					static int fastrpc_device_release(struct inode *inode, struct file *file)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data;
 | 
						struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data;
 | 
				
			||||||
| 
						 | 
					@ -722,6 +853,8 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
 | 
				
			||||||
	struct fastrpc_invoke_ctx *ctx, *n;
 | 
						struct fastrpc_invoke_ctx *ctx, *n;
 | 
				
			||||||
	struct fastrpc_map *map, *m;
 | 
						struct fastrpc_map *map, *m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fastrpc_release_current_dsp_process(fl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock(&cctx->lock);
 | 
						spin_lock(&cctx->lock);
 | 
				
			||||||
	list_del(&fl->user);
 | 
						list_del(&fl->user);
 | 
				
			||||||
	spin_unlock(&cctx->lock);
 | 
						spin_unlock(&cctx->lock);
 | 
				
			||||||
| 
						 | 
					@ -773,6 +906,23 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int fastrpc_init_attach(struct fastrpc_user *fl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fastrpc_invoke_args args[1];
 | 
				
			||||||
 | 
						int tgid = fl->tgid;
 | 
				
			||||||
 | 
						u32 sc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args[0].ptr = (u64)(uintptr_t) &tgid;
 | 
				
			||||||
 | 
						args[0].length = sizeof(tgid);
 | 
				
			||||||
 | 
						args[0].fd = -1;
 | 
				
			||||||
 | 
						args[0].reserved = 0;
 | 
				
			||||||
 | 
						sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0);
 | 
				
			||||||
 | 
						fl->pd = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
 | 
				
			||||||
 | 
									       sc, &args[0]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp)
 | 
					static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct fastrpc_invoke_args *args = NULL;
 | 
						struct fastrpc_invoke_args *args = NULL;
 | 
				
			||||||
| 
						 | 
					@ -814,6 +964,12 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
 | 
				
			||||||
	case FASTRPC_IOCTL_INVOKE:
 | 
						case FASTRPC_IOCTL_INVOKE:
 | 
				
			||||||
		err = fastrpc_invoke(fl, argp);
 | 
							err = fastrpc_invoke(fl, argp);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case FASTRPC_IOCTL_INIT_ATTACH:
 | 
				
			||||||
 | 
							err = fastrpc_init_attach(fl);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case FASTRPC_IOCTL_INIT_CREATE:
 | 
				
			||||||
 | 
							err = fastrpc_init_create_process(fl, argp);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		err = -ENOTTY;
 | 
							err = -ENOTTY;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@
 | 
				
			||||||
#include <linux/types.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FASTRPC_IOCTL_INVOKE		_IOWR('R', 3, struct fastrpc_invoke)
 | 
					#define FASTRPC_IOCTL_INVOKE		_IOWR('R', 3, struct fastrpc_invoke)
 | 
				
			||||||
 | 
					#define FASTRPC_IOCTL_INIT_ATTACH	_IO('R', 4)
 | 
				
			||||||
 | 
					#define FASTRPC_IOCTL_INIT_CREATE	_IOWR('R', 5, struct fastrpc_init_create)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct fastrpc_invoke_args {
 | 
					struct fastrpc_invoke_args {
 | 
				
			||||||
	__u64 ptr;
 | 
						__u64 ptr;
 | 
				
			||||||
| 
						 | 
					@ -20,4 +22,12 @@ struct fastrpc_invoke {
 | 
				
			||||||
	__u64 args;
 | 
						__u64 args;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fastrpc_init_create {
 | 
				
			||||||
 | 
						__u32 filelen;	/* elf file length */
 | 
				
			||||||
 | 
						__s32 filefd;	/* fd for the file */
 | 
				
			||||||
 | 
						__u32 attrs;
 | 
				
			||||||
 | 
						__u32 siglen;
 | 
				
			||||||
 | 
						__u64 file;	/* pointer to elf file */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __QCOM_FASTRPC_H__ */
 | 
					#endif /* __QCOM_FASTRPC_H__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue