Commit 3b404e37 authored by Pavel Emelyanov's avatar Pavel Emelyanov

parasite: Introduce generic syscall-calling function

This one calls a syscon on seized task. Existing mmap/munmap
just use one.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 9428f3a9
......@@ -59,4 +59,12 @@ struct pstree_item;
extern int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *item);
extern int parasite_fini_threads_seized(struct parasite_ctl *ctl, struct pstree_item *item);
int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6);
#endif /* PARASITE_SYSCALL_H_ */
......@@ -244,50 +244,55 @@ static int parasite_execute(unsigned int cmd, struct parasite_ctl *ctl)
return parasite_execute_by_pid(cmd, ctl, ctl->pid);
}
static void *mmap_seized(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6)
{
user_regs_struct_t regs = ctl->regs_orig;
void *map = NULL;
int ret;
int err;
regs.ax = (unsigned long)__NR_mmap; /* mmap */
regs.di = (unsigned long)addr; /* @addr */
regs.si = (unsigned long)length; /* @length */
regs.dx = (unsigned long)prot; /* @prot */
regs.r10 = (unsigned long)flags; /* @flags */
regs.r8 = (unsigned long)fd; /* @fd */
regs.r9 = (unsigned long)offset; /* @offset */
regs.ax = (unsigned long)nr;
regs.di = arg1;
regs.si = arg2;
regs.dx = arg3;
regs.r10 = arg4;
regs.r8 = arg5;
regs.r9 = arg6;
parasite_setup_regs(ctl->syscall_ip, &regs);
err = __parasite_execute(ctl, ctl->pid, &regs);
if (err)
return err;
ret = __parasite_execute(ctl, ctl->pid, &regs);
if (ret)
goto err;
if ((long)regs.ax > 0)
map = (void *)regs.ax;
err:
return map;
*ret = regs.ax;
return 0;
}
static int munmap_seized(struct parasite_ctl *ctl, void *addr, size_t length)
static void *mmap_seized(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
{
user_regs_struct_t regs = ctl->regs_orig;
int ret;
unsigned long map;
int err;
regs.ax = (unsigned long)__NR_munmap; /* mmap */
regs.di = (unsigned long)addr; /* @addr */
regs.si = (unsigned long)length; /* @length */
err = syscall_seized(ctl, __NR_mmap, &map,
(unsigned long)addr, length, prot, flags, fd, offset);
if (err < 0 || (long)map < 0)
map = 0;
parasite_setup_regs(ctl->syscall_ip, &regs);
return (void *)map;
}
ret = __parasite_execute(ctl, ctl->pid, &regs);
if (!ret)
ret = (int)regs.ax;
static int munmap_seized(struct parasite_ctl *ctl, void *addr, size_t length)
{
unsigned long x;
return ret;
return syscall_seized(ctl, __NR_munmap, &x,
(unsigned long)addr, length, 0, 0, 0, 0);
}
static int gen_parasite_saddr(struct sockaddr_un *saddr, int key)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment