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; ...@@ -59,4 +59,12 @@ struct pstree_item;
extern int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *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); 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_ */ #endif /* PARASITE_SYSCALL_H_ */
...@@ -244,50 +244,55 @@ static int parasite_execute(unsigned int cmd, struct parasite_ctl *ctl) ...@@ -244,50 +244,55 @@ static int parasite_execute(unsigned int cmd, struct parasite_ctl *ctl)
return parasite_execute_by_pid(cmd, ctl, ctl->pid); return parasite_execute_by_pid(cmd, ctl, ctl->pid);
} }
static void *mmap_seized(struct parasite_ctl *ctl, int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
void *addr, size_t length, int prot, unsigned long arg1,
int flags, int fd, off_t offset) unsigned long arg2,
unsigned long arg3,
unsigned long arg4,
unsigned long arg5,
unsigned long arg6)
{ {
user_regs_struct_t regs = ctl->regs_orig; user_regs_struct_t regs = ctl->regs_orig;
void *map = NULL; int err;
int ret;
regs.ax = (unsigned long)__NR_mmap; /* mmap */ regs.ax = (unsigned long)nr;
regs.di = (unsigned long)addr; /* @addr */ regs.di = arg1;
regs.si = (unsigned long)length; /* @length */ regs.si = arg2;
regs.dx = (unsigned long)prot; /* @prot */ regs.dx = arg3;
regs.r10 = (unsigned long)flags; /* @flags */ regs.r10 = arg4;
regs.r8 = (unsigned long)fd; /* @fd */ regs.r8 = arg5;
regs.r9 = (unsigned long)offset; /* @offset */ regs.r9 = arg6;
parasite_setup_regs(ctl->syscall_ip, &regs); 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); *ret = regs.ax;
if (ret) return 0;
goto err;
if ((long)regs.ax > 0)
map = (void *)regs.ax;
err:
return map;
} }
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; unsigned long map;
int ret; int err;
regs.ax = (unsigned long)__NR_munmap; /* mmap */ err = syscall_seized(ctl, __NR_mmap, &map,
regs.di = (unsigned long)addr; /* @addr */ (unsigned long)addr, length, prot, flags, fd, offset);
regs.si = (unsigned long)length; /* @length */ 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); static int munmap_seized(struct parasite_ctl *ctl, void *addr, size_t length)
if (!ret) {
ret = (int)regs.ax; 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) 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