mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "msm:ADSPRPC: memory map updates to remote process"
This commit is contained in:
commit
0070b55b6b
3 changed files with 598 additions and 90 deletions
|
|
@ -863,16 +863,22 @@ static int fastrpc_alloc_cma_memory(dma_addr_t *region_phys, void **vaddr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
|
||||
static int fastrpc_mmap_remove(struct fastrpc_file *fl, int fd, uintptr_t va,
|
||||
size_t len, struct fastrpc_mmap **ppmap)
|
||||
{
|
||||
struct fastrpc_mmap *match = NULL, *map;
|
||||
struct hlist_node *n;
|
||||
struct fastrpc_apps *me = &gfa;
|
||||
|
||||
/*
|
||||
* Search for a mapping by matching fd, remote address and length.
|
||||
* For backward compatibility, search for a mapping by matching is
|
||||
* limited to remote address and length when passed fd < 0.
|
||||
*/
|
||||
|
||||
spin_lock(&me->hlock);
|
||||
hlist_for_each_entry_safe(map, n, &me->maps, hn) {
|
||||
if (map->raddr == va &&
|
||||
if ((fd < 0 || map->fd == fd) && map->raddr == va &&
|
||||
map->raddr + map->len == va + len &&
|
||||
map->refs == 1) {
|
||||
match = map;
|
||||
|
|
@ -886,7 +892,7 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
|
|||
return 0;
|
||||
}
|
||||
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
|
||||
if (map->raddr == va &&
|
||||
if ((fd < 0 || map->fd == fd) && map->raddr == va &&
|
||||
map->raddr + map->len == va + len &&
|
||||
map->refs == 1) {
|
||||
match = map;
|
||||
|
|
@ -898,7 +904,7 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
|
|||
*ppmap = match;
|
||||
return 0;
|
||||
}
|
||||
return -ENOTTY;
|
||||
return -ETOOMANYREFS;
|
||||
}
|
||||
|
||||
static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
|
||||
|
|
@ -3353,6 +3359,106 @@ bail:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_mem_map_to_dsp(struct fastrpc_file *fl, int fd, int offset,
|
||||
uint32_t flags, uintptr_t va, uint64_t phys,
|
||||
size_t size, uintptr_t *raddr)
|
||||
{
|
||||
struct fastrpc_ioctl_invoke_async ioctl;
|
||||
struct smq_phy_page page;
|
||||
remote_arg_t ra[4];
|
||||
int err = 0;
|
||||
struct {
|
||||
int pid;
|
||||
int fd;
|
||||
int offset;
|
||||
uint32_t flags;
|
||||
uint64_t vaddrin;
|
||||
int num;
|
||||
int data_len;
|
||||
} inargs;
|
||||
struct {
|
||||
uint64_t vaddrout;
|
||||
} routargs;
|
||||
|
||||
inargs.pid = fl->tgid;
|
||||
inargs.fd = fd;
|
||||
inargs.offset = offset;
|
||||
inargs.vaddrin = (uintptr_t)va;
|
||||
inargs.flags = flags;
|
||||
inargs.num = sizeof(page);
|
||||
inargs.data_len = 0;
|
||||
ra[0].buf.pv = (void *)&inargs;
|
||||
ra[0].buf.len = sizeof(inargs);
|
||||
page.addr = phys;
|
||||
page.size = size;
|
||||
ra[1].buf.pv = (void *)&page;
|
||||
ra[1].buf.len = sizeof(page);
|
||||
ra[2].buf.pv = (void *)&page;
|
||||
ra[2].buf.len = 0;
|
||||
ra[3].buf.pv = (void *)&routargs;
|
||||
ra[3].buf.len = sizeof(routargs);
|
||||
|
||||
ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
|
||||
ioctl.inv.sc = REMOTE_SCALARS_MAKE(10, 3, 1);
|
||||
ioctl.inv.pra = ra;
|
||||
ioctl.fds = NULL;
|
||||
ioctl.attrs = NULL;
|
||||
ioctl.crc = NULL;
|
||||
ioctl.job = NULL;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
|
||||
FASTRPC_MODE_PARALLEL, 1, &ioctl)));
|
||||
if (err)
|
||||
goto bail;
|
||||
if (raddr)
|
||||
*raddr = (uintptr_t)routargs.vaddrout;
|
||||
bail:
|
||||
if (err) {
|
||||
pr_err("adsprpc: %s failed. err 0x%x fd %d len 0x%x\n",
|
||||
__func__, err, fd, size);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_mem_unmap_to_dsp(struct fastrpc_file *fl, int fd,
|
||||
uint32_t flags, uintptr_t va,
|
||||
uint64_t phys, size_t size)
|
||||
{
|
||||
struct fastrpc_ioctl_invoke_async ioctl;
|
||||
remote_arg_t ra[1];
|
||||
int err = 0;
|
||||
struct {
|
||||
int pid;
|
||||
int fd;
|
||||
uint64_t vaddrin;
|
||||
uint64_t len;
|
||||
} inargs;
|
||||
|
||||
inargs.pid = fl->tgid;
|
||||
inargs.fd = fd;
|
||||
inargs.vaddrin = (uint64_t)va;
|
||||
inargs.len = (uint64_t)size;
|
||||
ra[0].buf.pv = (void *)&inargs;
|
||||
ra[0].buf.len = sizeof(inargs);
|
||||
|
||||
ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
|
||||
ioctl.inv.sc = REMOTE_SCALARS_MAKE(11, 1, 0);
|
||||
ioctl.inv.pra = ra;
|
||||
ioctl.fds = NULL;
|
||||
ioctl.attrs = NULL;
|
||||
ioctl.crc = NULL;
|
||||
ioctl.job = NULL;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
|
||||
FASTRPC_MODE_PARALLEL, 1, &ioctl)));
|
||||
if (err)
|
||||
goto bail;
|
||||
bail:
|
||||
if (err) {
|
||||
pr_err("adsprpc: %s failed. err 0x%x fd %d len 0x%x\n",
|
||||
__func__, err, fd, size);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_unmap_on_dsp(struct fastrpc_file *fl,
|
||||
uintptr_t raddr, uint64_t phys, size_t size, uint32_t flags)
|
||||
{
|
||||
|
|
@ -3686,7 +3792,7 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl,
|
|||
}
|
||||
|
||||
mutex_lock(&fl->map_mutex);
|
||||
VERIFY(err, !fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, &map));
|
||||
VERIFY(err, !fastrpc_mmap_remove(fl, -1, ud->vaddrout, ud->size, &map));
|
||||
mutex_unlock(&fl->map_mutex);
|
||||
if (err)
|
||||
goto bail;
|
||||
|
|
@ -3739,6 +3845,106 @@ bail:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_internal_mem_map(struct fastrpc_file *fl,
|
||||
struct fastrpc_ioctl_mem_map *ud)
|
||||
{
|
||||
int err = 0;
|
||||
struct fastrpc_mmap *map = NULL;
|
||||
|
||||
VERIFY(err, fl->dsp_proc_init == 1);
|
||||
if (err) {
|
||||
pr_err("adsprpc: ERROR: %s: user application %s trying to map without initialization\n",
|
||||
__func__, current->comm);
|
||||
err = EBADR;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* create SMMU mapping */
|
||||
mutex_lock(&fl->map_mutex);
|
||||
VERIFY(err, !fastrpc_mmap_create(fl, ud->m.fd, ud->m.attrs,
|
||||
ud->m.vaddrin, ud->m.length,
|
||||
ud->m.flags, &map));
|
||||
mutex_unlock(&fl->map_mutex);
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
if (map->raddr) {
|
||||
err = -EEXIST;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* create DSP mapping */
|
||||
VERIFY(err, !(err = fastrpc_mem_map_to_dsp(fl, ud->m.fd, ud->m.offset,
|
||||
ud->m.flags, map->va, map->phys, ud->m.length, &map->raddr)));
|
||||
if (err)
|
||||
goto bail;
|
||||
ud->m.vaddrout = map->raddr;
|
||||
bail:
|
||||
if (err) {
|
||||
pr_err("adsprpc: %s failed to map fd %d flags %d err %d\n",
|
||||
__func__, ud->m.fd, ud->m.flags, err);
|
||||
if (map) {
|
||||
mutex_lock(&fl->map_mutex);
|
||||
fastrpc_mmap_free(map, 0);
|
||||
mutex_unlock(&fl->map_mutex);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_internal_mem_unmap(struct fastrpc_file *fl,
|
||||
struct fastrpc_ioctl_mem_unmap *ud)
|
||||
{
|
||||
int err = 0;
|
||||
struct fastrpc_mmap *map = NULL;
|
||||
|
||||
VERIFY(err, fl->dsp_proc_init == 1);
|
||||
if (err) {
|
||||
pr_err("adsprpc: ERROR: %s: user application %s trying to map without initialization\n",
|
||||
__func__, current->comm);
|
||||
err = EBADR;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
mutex_lock(&fl->map_mutex);
|
||||
VERIFY(err, !fastrpc_mmap_remove(fl, ud->um.fd,
|
||||
(uintptr_t)ud->um.vaddr, ud->um.length, &map));
|
||||
mutex_unlock(&fl->map_mutex);
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
VERIFY(err, map->flags == FASTRPC_MAP_FD ||
|
||||
map->flags == FASTRPC_MAP_FD_DELAYED ||
|
||||
map->flags == FASTRPC_MAP_STATIC);
|
||||
if (err) {
|
||||
err = -EBADMSG;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* remove mapping on DSP */
|
||||
VERIFY(err, !(err = fastrpc_mem_unmap_to_dsp(fl, map->fd, map->flags,
|
||||
map->raddr, map->phys, map->size)));
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
/* remove SMMU mapping */
|
||||
mutex_lock(&fl->map_mutex);
|
||||
fastrpc_mmap_free(map, 0);
|
||||
mutex_unlock(&fl->map_mutex);
|
||||
map = NULL;
|
||||
bail:
|
||||
if (err) {
|
||||
pr_err("adsprpc: %s failed to unmap fd %d addr 0x%llx length 0x%x err 0x%x\n",
|
||||
__func__, ud->um.fd, ud->um.vaddr, ud->um.length, err);
|
||||
/* Add back to map list in case of error to unmap on DSP */
|
||||
if (map) {
|
||||
mutex_lock(&fl->map_mutex);
|
||||
fastrpc_mmap_add(map);
|
||||
mutex_unlock(&fl->map_mutex);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_internal_mmap(struct fastrpc_file *fl,
|
||||
struct fastrpc_ioctl_mmap *ud)
|
||||
|
|
@ -4735,26 +4941,130 @@ bail:
|
|||
return err;
|
||||
}
|
||||
|
||||
static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
|
||||
unsigned long ioctl_param)
|
||||
union fastrpc_ioctl_param {
|
||||
struct fastrpc_ioctl_invoke_async inv;
|
||||
struct fastrpc_ioctl_mem_map mem_map;
|
||||
struct fastrpc_ioctl_mem_unmap mem_unmap;
|
||||
struct fastrpc_ioctl_mmap mmap;
|
||||
struct fastrpc_ioctl_mmap_64 mmap64;
|
||||
struct fastrpc_ioctl_munmap munmap;
|
||||
struct fastrpc_ioctl_munmap_64 munmap64;
|
||||
struct fastrpc_ioctl_munmap_fd munmap_fd;
|
||||
struct fastrpc_ioctl_init_attrs init;
|
||||
struct fastrpc_ioctl_perf perf;
|
||||
struct fastrpc_ioctl_control cp;
|
||||
struct fastrpc_ioctl_capability cap;
|
||||
struct fastrpc_ioctl_invoke2 inv2;
|
||||
};
|
||||
|
||||
static inline int fastrpc_mmap_device_ioctl(struct fastrpc_file *fl,
|
||||
unsigned int ioctl_num, union fastrpc_ioctl_param *p,
|
||||
void *param)
|
||||
{
|
||||
union {
|
||||
struct fastrpc_ioctl_invoke_async inv;
|
||||
struct fastrpc_ioctl_mmap mmap;
|
||||
struct fastrpc_ioctl_mmap_64 mmap64;
|
||||
struct fastrpc_ioctl_munmap munmap;
|
||||
struct fastrpc_ioctl_munmap_64 munmap64;
|
||||
struct fastrpc_ioctl_munmap_fd munmap_fd;
|
||||
struct fastrpc_ioctl_init_attrs init;
|
||||
struct fastrpc_ioctl_perf perf;
|
||||
struct fastrpc_ioctl_control cp;
|
||||
struct fastrpc_ioctl_capability cap;
|
||||
struct fastrpc_ioctl_invoke2 inv2;
|
||||
} p;
|
||||
union {
|
||||
struct fastrpc_ioctl_mmap mmap;
|
||||
struct fastrpc_ioctl_munmap munmap;
|
||||
} i;
|
||||
int err = 0;
|
||||
|
||||
switch (ioctl_num) {
|
||||
case FASTRPC_IOCTL_MEM_MAP:
|
||||
K_COPY_FROM_USER(err, 0, &p->mem_map, param,
|
||||
sizeof(p->mem_map));
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_mem_map(fl,
|
||||
&p->mem_map)));
|
||||
if (err)
|
||||
goto bail;
|
||||
K_COPY_TO_USER(err, 0, param, &p->mem_map, sizeof(p->mem_map));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MEM_UNMAP:
|
||||
K_COPY_FROM_USER(err, 0, &p->mem_unmap, param,
|
||||
sizeof(p->mem_unmap));
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_mem_unmap(fl,
|
||||
&p->mem_unmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
K_COPY_TO_USER(err, 0, param, &p->mem_unmap,
|
||||
sizeof(p->mem_unmap));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MMAP:
|
||||
K_COPY_FROM_USER(err, 0, &p->mmap, param,
|
||||
sizeof(p->mmap));
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p->mmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
K_COPY_TO_USER(err, 0, param, &p->mmap, sizeof(p->mmap));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MUNMAP:
|
||||
K_COPY_FROM_USER(err, 0, &p->munmap, param,
|
||||
sizeof(p->munmap));
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
|
||||
&p->munmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MMAP_64:
|
||||
K_COPY_FROM_USER(err, 0, &p->mmap64, param,
|
||||
sizeof(p->mmap64));
|
||||
if (err)
|
||||
goto bail;
|
||||
get_fastrpc_ioctl_mmap_64(&p->mmap64, &i.mmap);
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &i.mmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
put_fastrpc_ioctl_mmap_64(&p->mmap64, &i.mmap);
|
||||
K_COPY_TO_USER(err, 0, param, &p->mmap64, sizeof(p->mmap64));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MUNMAP_64:
|
||||
K_COPY_FROM_USER(err, 0, &p->munmap64, param,
|
||||
sizeof(p->munmap64));
|
||||
if (err)
|
||||
goto bail;
|
||||
get_fastrpc_ioctl_munmap_64(&p->munmap64, &i.munmap);
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
|
||||
&i.munmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MUNMAP_FD:
|
||||
K_COPY_FROM_USER(err, 0, &p->munmap_fd, param,
|
||||
sizeof(p->munmap_fd));
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_munmap_fd(fl,
|
||||
&p->munmap_fd)));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
default:
|
||||
err = -ENOTTY;
|
||||
pr_info("bad ioctl: %d\n", ioctl_num);
|
||||
break;
|
||||
}
|
||||
bail:
|
||||
return err;
|
||||
}
|
||||
|
||||
static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
|
||||
unsigned long ioctl_param)
|
||||
{
|
||||
union fastrpc_ioctl_param p;
|
||||
void *param = (char *)ioctl_param;
|
||||
struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
|
||||
int size = 0, err = 0;
|
||||
|
|
@ -4811,63 +5121,6 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
|
|||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MMAP:
|
||||
K_COPY_FROM_USER(err, 0, &p.mmap, param,
|
||||
sizeof(p.mmap));
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MUNMAP:
|
||||
K_COPY_FROM_USER(err, 0, &p.munmap, param,
|
||||
sizeof(p.munmap));
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
|
||||
&p.munmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MMAP_64:
|
||||
K_COPY_FROM_USER(err, 0, &p.mmap64, param,
|
||||
sizeof(p.mmap64));
|
||||
if (err)
|
||||
goto bail;
|
||||
get_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &i.mmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
put_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
|
||||
K_COPY_TO_USER(err, 0, param, &p.mmap64, sizeof(p.mmap64));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MUNMAP_64:
|
||||
K_COPY_FROM_USER(err, 0, &p.munmap64, param,
|
||||
sizeof(p.munmap64));
|
||||
if (err)
|
||||
goto bail;
|
||||
get_fastrpc_ioctl_munmap_64(&p.munmap64, &i.munmap);
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
|
||||
&i.munmap)));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_MUNMAP_FD:
|
||||
K_COPY_FROM_USER(err, 0, &p.munmap_fd, param,
|
||||
sizeof(p.munmap_fd));
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, 0 == (err = fastrpc_internal_munmap_fd(fl,
|
||||
&p.munmap_fd)));
|
||||
if (err)
|
||||
goto bail;
|
||||
break;
|
||||
case FASTRPC_IOCTL_SETMODE:
|
||||
err = fastrpc_setmode(ioctl_param, fl);
|
||||
break;
|
||||
|
|
@ -4906,6 +5159,21 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
|
|||
case FASTRPC_IOCTL_GET_DSP_INFO:
|
||||
err = fastrpc_get_dsp_info(&p.cap, param, fl);
|
||||
break;
|
||||
case FASTRPC_IOCTL_MEM_MAP:
|
||||
/* fall through */
|
||||
case FASTRPC_IOCTL_MEM_UNMAP:
|
||||
/* fall through */
|
||||
case FASTRPC_IOCTL_MMAP:
|
||||
/* fall through */
|
||||
case FASTRPC_IOCTL_MUNMAP:
|
||||
/* fall through */
|
||||
case FASTRPC_IOCTL_MMAP_64:
|
||||
/* fall through */
|
||||
case FASTRPC_IOCTL_MUNMAP_64:
|
||||
/* fall through */
|
||||
case FASTRPC_IOCTL_MUNMAP_FD:
|
||||
err = fastrpc_mmap_device_ioctl(fl, ioctl_num, &p, param);
|
||||
break;
|
||||
default:
|
||||
err = -ENOTTY;
|
||||
pr_info("bad ioctl: %d\n", ioctl_num);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@
|
|||
struct compat_fastrpc_ioctl_capability)
|
||||
#define COMPAT_FASTRPC_IOCTL_INVOKE2 \
|
||||
_IOWR('R', 18, struct compat_fastrpc_ioctl_invoke2)
|
||||
#define COMPAT_FASTRPC_IOCTL_MEM_MAP \
|
||||
_IOWR('R', 19, struct compat_fastrpc_ioctl_mem_map)
|
||||
#define COMPAT_FASTRPC_IOCTL_MEM_UNMAP \
|
||||
_IOWR('R', 20, struct compat_fastrpc_ioctl_mem_unmap)
|
||||
|
||||
struct compat_remote_buf {
|
||||
compat_uptr_t pv; /* buffer pointer */
|
||||
|
|
@ -89,6 +93,38 @@ struct compat_fastrpc_ioctl_invoke2 {
|
|||
compat_int_t err; /* reserved */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_mem_map {
|
||||
compat_int_t fd; /* ion fd */
|
||||
compat_int_t offset; /* buffer offset */
|
||||
compat_uint_t flags; /* flags to control memory map */
|
||||
compat_uint_t attrs; /* buffer attributes used for SMMU mapping */
|
||||
compat_uptr_t vaddrin; /* virtual address */
|
||||
compat_size_t length; /* buffer length */
|
||||
compat_u64 vaddrout; /* dsp virtual address */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_mem_map {
|
||||
compat_int_t version;
|
||||
union {
|
||||
struct compat_fastrpc_mem_map m;
|
||||
compat_int_t reserved[MAP_RESERVED_NUM];
|
||||
};
|
||||
};
|
||||
|
||||
struct compat_fastrpc_mem_unmap {
|
||||
compat_int_t fd; /* ion fd */
|
||||
compat_u64 vaddr; /* dsp virtual address */
|
||||
compat_size_t length; /* buffer length */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_mem_unmap {
|
||||
compat_int_t version;
|
||||
union {
|
||||
struct compat_fastrpc_mem_unmap um;
|
||||
compat_int_t reserved[UNMAP_RESERVED_NUM];
|
||||
};
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_mmap {
|
||||
compat_int_t fd; /* ion fd */
|
||||
compat_uint_t flags; /* flags for dsp to map with */
|
||||
|
|
@ -372,6 +408,74 @@ static int compat_fastrpc_ioctl_invoke2(struct file *filp,
|
|||
FASTRPC_IOCTL_INVOKE2, (unsigned long)inv);
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_mem_map(
|
||||
struct compat_fastrpc_ioctl_mem_map __user *map32,
|
||||
struct fastrpc_ioctl_mem_map __user *map)
|
||||
{
|
||||
compat_uint_t u;
|
||||
compat_int_t i;
|
||||
compat_size_t s;
|
||||
compat_uptr_t p;
|
||||
int err;
|
||||
|
||||
err = get_user(i, &map32->version);
|
||||
if (err || i != 0)
|
||||
return -EINVAL;
|
||||
|
||||
err = put_user(i, &map->version);
|
||||
err |= get_user(i, &map32->m.fd);
|
||||
err |= put_user(i, &map->m.fd);
|
||||
err |= get_user(i, &map32->m.offset);
|
||||
err |= put_user(i, &map->m.offset);
|
||||
err |= get_user(u, &map32->m.flags);
|
||||
err |= put_user(u, &map->m.flags);
|
||||
err |= get_user(p, &map32->m.vaddrin);
|
||||
err |= put_user(p, &map->m.vaddrin);
|
||||
err |= get_user(s, &map32->m.length);
|
||||
err |= put_user(s, &map->m.length);
|
||||
err |= get_user(u, &map32->m.attrs);
|
||||
err |= put_user(u, &map->m.attrs);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_put_fastrpc_ioctl_mem_map(
|
||||
struct compat_fastrpc_ioctl_mem_map __user *map32,
|
||||
struct fastrpc_ioctl_mem_map __user *map)
|
||||
{
|
||||
compat_u64 p;
|
||||
int err;
|
||||
|
||||
err = get_user(p, &map->m.vaddrout);
|
||||
err |= put_user(p, &map32->m.vaddrout);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_mem_unmap(
|
||||
struct compat_fastrpc_ioctl_mem_unmap __user *unmap32,
|
||||
struct fastrpc_ioctl_mem_unmap __user *unmap)
|
||||
{
|
||||
compat_int_t i;
|
||||
compat_size_t s;
|
||||
compat_u64 p;
|
||||
int err;
|
||||
|
||||
err = get_user(i, &unmap32->version);
|
||||
if (err || i != 0)
|
||||
return -EINVAL;
|
||||
|
||||
err = put_user(i, &unmap->version);
|
||||
err |= get_user(i, &unmap32->um.fd);
|
||||
err |= put_user(i, &unmap->um.fd);
|
||||
err |= get_user(p, &unmap32->um.vaddr);
|
||||
err |= put_user(p, &unmap->um.vaddr);
|
||||
err |= get_user(s, &unmap32->um.length);
|
||||
err |= put_user(s, &unmap->um.length);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_mmap(
|
||||
struct compat_fastrpc_ioctl_mmap __user *map32,
|
||||
struct fastrpc_ioctl_mmap __user *map)
|
||||
|
|
@ -661,25 +765,54 @@ static int compat_fastrpc_get_dsp_info(struct file *filp,
|
|||
return err;
|
||||
}
|
||||
|
||||
long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
static inline long compat_fastrpc_mmap_device_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
|
||||
return -ENOTTY;
|
||||
|
||||
switch (cmd) {
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_FD:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_CRC:
|
||||
case COMPAT_FASTRPC_IOCTL_MEM_MAP:
|
||||
{
|
||||
return compat_fastrpc_ioctl_invoke(filp, cmd, arg);
|
||||
struct compat_fastrpc_ioctl_mem_map __user *map32;
|
||||
struct fastrpc_ioctl_mem_map __user *map;
|
||||
long ret;
|
||||
|
||||
map32 = compat_ptr(arg);
|
||||
map = compat_alloc_user_space(sizeof(*map));
|
||||
if (map == NULL)
|
||||
return -EFAULT;
|
||||
|
||||
err = compat_get_fastrpc_ioctl_mem_map(map32, map);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MEM_MAP,
|
||||
(unsigned long)map);
|
||||
if (ret)
|
||||
return ret;
|
||||
VERIFY(err, 0 == compat_put_fastrpc_ioctl_mem_map(map32, map));
|
||||
return err;
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE2:
|
||||
case COMPAT_FASTRPC_IOCTL_MEM_UNMAP:
|
||||
{
|
||||
return compat_fastrpc_ioctl_invoke2(filp, cmd, arg);
|
||||
struct compat_fastrpc_ioctl_mem_unmap __user *unmap32;
|
||||
struct fastrpc_ioctl_mem_unmap __user *unmap;
|
||||
long ret;
|
||||
|
||||
unmap32 = compat_ptr(arg);
|
||||
unmap = compat_alloc_user_space(sizeof(*unmap));
|
||||
if (unmap == NULL)
|
||||
return -EFAULT;
|
||||
|
||||
err = compat_get_fastrpc_ioctl_mem_unmap(unmap32, unmap);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MEM_UNMAP,
|
||||
(unsigned long)unmap);
|
||||
if (ret)
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_MMAP:
|
||||
{
|
||||
|
|
@ -740,6 +873,31 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
|
|||
return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MUNMAP,
|
||||
(unsigned long)unmap);
|
||||
}
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
|
||||
long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
|
||||
return -ENOTTY;
|
||||
|
||||
switch (cmd) {
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_FD:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_CRC:
|
||||
{
|
||||
return compat_fastrpc_ioctl_invoke(filp, cmd, arg);
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE2:
|
||||
{
|
||||
return compat_fastrpc_ioctl_invoke2(filp, cmd, arg);
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_MUNMAP_64:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_munmap_64 __user *unmap32;
|
||||
|
|
@ -814,6 +972,16 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
|
|||
{
|
||||
return compat_fastrpc_get_dsp_info(filp, arg);
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_MEM_MAP:
|
||||
/* fall through */
|
||||
case COMPAT_FASTRPC_IOCTL_MEM_UNMAP:
|
||||
/* fall through */
|
||||
case COMPAT_FASTRPC_IOCTL_MMAP:
|
||||
/* fall through */
|
||||
case COMPAT_FASTRPC_IOCTL_MMAP_64:
|
||||
/* fall through */
|
||||
case COMPAT_FASTRPC_IOCTL_MUNMAP:
|
||||
return compat_fastrpc_mmap_device_ioctl(filp, cmd, arg);
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@
|
|||
#define FASTRPC_IOCTL_GET_DSP_INFO \
|
||||
_IOWR('R', 17, struct fastrpc_ioctl_capability)
|
||||
#define FASTRPC_IOCTL_INVOKE2 _IOWR('R', 18, struct fastrpc_ioctl_invoke2)
|
||||
|
||||
#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 19, struct fastrpc_ioctl_mem_map)
|
||||
#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 20, struct fastrpc_ioctl_mem_unmap)
|
||||
|
||||
#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
|
||||
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
|
||||
|
|
@ -271,6 +272,77 @@ struct fastrpc_ioctl_munmap_fd {
|
|||
ssize_t len; /* length */
|
||||
};
|
||||
|
||||
/**
|
||||
* Control flags for mapping memory on DSP user process
|
||||
*/
|
||||
enum fastrpc_map_flags {
|
||||
/**
|
||||
* Map memory pages with RW- permission and CACHE WRITEBACK.
|
||||
* The driver is responsible for cache maintenance when passed
|
||||
* the buffer to FastRPC calls. Same virtual address will be
|
||||
* assigned for subsequent FastRPC calls.
|
||||
*/
|
||||
FASTRPC_MAP_STATIC = 0,
|
||||
|
||||
/* Reserved */
|
||||
FASTRPC_MAP_RESERVED,
|
||||
|
||||
/**
|
||||
* Map memory pages with RW- permission and CACHE WRITEBACK.
|
||||
* Mapping tagged with a file descriptor. User is responsible for
|
||||
* CPU and DSP cache maintenance for the buffer. Get virtual address
|
||||
* of buffer on DSP using HAP_mmap_get() and HAP_mmap_put() APIs.
|
||||
*/
|
||||
FASTRPC_MAP_FD = 2,
|
||||
|
||||
/**
|
||||
* Mapping delayed until user call HAP_mmap() and HAP_munmap()
|
||||
* functions on DSP. It is useful to map a buffer with cache modes
|
||||
* other than default modes. User is responsible for CPU and DSP
|
||||
* cache maintenance for the buffer.
|
||||
*/
|
||||
FASTRPC_MAP_FD_DELAYED,
|
||||
FASTRPC_MAP_MAX,
|
||||
};
|
||||
|
||||
struct fastrpc_mem_map {
|
||||
int fd; /* ion fd */
|
||||
int offset; /* buffer offset */
|
||||
uint32_t flags; /* flags defined in enum fastrpc_map_flags */
|
||||
int attrs; /* buffer attributes used for SMMU mapping */
|
||||
uintptr_t vaddrin; /* buffer virtual address */
|
||||
size_t length; /* buffer length */
|
||||
uint64_t vaddrout; /* [out] remote virtual address */
|
||||
};
|
||||
|
||||
/* Map and unmap IOCTL methods reserved memory size for future extensions */
|
||||
#define MAP_RESERVED_NUM (14)
|
||||
#define UNMAP_RESERVED_NUM (10)
|
||||
|
||||
/* map memory to DSP device */
|
||||
struct fastrpc_ioctl_mem_map {
|
||||
int version; /* Initial version 0 */
|
||||
union {
|
||||
struct fastrpc_mem_map m;
|
||||
int reserved[MAP_RESERVED_NUM];
|
||||
};
|
||||
};
|
||||
|
||||
struct fastrpc_mem_unmap {
|
||||
int fd; /* ion fd */
|
||||
uint64_t vaddr; /* remote process (dsp) virtual address */
|
||||
size_t length; /* buffer size */
|
||||
};
|
||||
|
||||
/* unmap memory to DSP device */
|
||||
struct fastrpc_ioctl_mem_unmap {
|
||||
int version; /* Initial version 0 */
|
||||
union {
|
||||
struct fastrpc_mem_unmap um;
|
||||
int reserved[UNMAP_RESERVED_NUM];
|
||||
};
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_perf { /* kernel performance data */
|
||||
uintptr_t data;
|
||||
uint32_t numkeys;
|
||||
|
|
|
|||
Loading…
Reference in a new issue