Skip to content

Commit

Permalink
misc: fastrpc: Add support for create remote init process
Browse files Browse the repository at this point in the history
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 <[email protected]>

Co-developed-by: Thierry Escande <[email protected]>
Signed-off-by: Thierry Escande <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
Srinivas-Kandagatla authored and gregkh committed Feb 12, 2019
1 parent c68cfb7 commit d73f71c
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 0 deletions.
156 changes: 156 additions & 0 deletions drivers/misc/fastrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
#define FASTRPC_MAX_CRCLIST 64
#define FASTRPC_PHYS(p) ((p) & 0xffffffff)
#define FASTRPC_CTX_MAX (256)
#define FASTRPC_INIT_HANDLE 1
#define FASTRPC_CTXID_MASK (0xFF0)
#define INIT_FILELEN_MAX (2 * 1024 * 1024)
#define INIT_MEMLEN_MAX (8 * 1024 * 1024)
#define FASTRPC_DEVICE_NAME "fastrpc"

/* Retrives number of input buffers from the scalars parameter */
Expand Down Expand Up @@ -59,6 +62,14 @@
#define FASTRPC_SCALARS(method, in, out) \
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)

static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp",
Expand Down Expand Up @@ -688,6 +699,109 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
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(
struct fastrpc_channel_ctx *cctx)
{
Expand Down Expand Up @@ -715,13 +829,32 @@ static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx,
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)
{
struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data;
struct fastrpc_channel_ctx *cctx = fl->cctx;
struct fastrpc_invoke_ctx *ctx, *n;
struct fastrpc_map *map, *m;

fastrpc_release_current_dsp_process(fl);

spin_lock(&cctx->lock);
list_del(&fl->user);
spin_unlock(&cctx->lock);
Expand Down Expand Up @@ -773,6 +906,23 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
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)
{
struct fastrpc_invoke_args *args = NULL;
Expand Down Expand Up @@ -814,6 +964,12 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
case FASTRPC_IOCTL_INVOKE:
err = fastrpc_invoke(fl, argp);
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:
err = -ENOTTY;
break;
Expand Down
10 changes: 10 additions & 0 deletions include/uapi/misc/fastrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <linux/types.h>

#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 {
__u64 ptr;
Expand All @@ -20,4 +22,12 @@ struct fastrpc_invoke {
__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__ */

0 comments on commit d73f71c

Please sign in to comment.