Commit 7db199c7 authored by Pavel Emelyanov's avatar Pavel Emelyanov

parasite: Remove double args copy

There's a shared memory between crtools and parasite. No need in copying
args back and forth, just get the args pointer in crtools and work on it.
Where not possible (misc, fds drain) do explicit memecpy (to be fixed).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7c8496f5
...@@ -222,15 +222,17 @@ err: ...@@ -222,15 +222,17 @@ err:
return ret; return ret;
} }
static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl, static void *parasite_args(struct parasite_ctl *ctl, int args_size)
pid_t pid, {
void *args, int args_size) BUG_ON(args_size > PARASITE_ARG_SIZE);
return ctl->addr_args;
}
static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl, pid_t pid)
{ {
int ret; int ret;
user_regs_struct_t regs_orig, regs; user_regs_struct_t regs_orig, regs;
BUG_ON(args_size > PARASITE_ARG_SIZE);
if (ctl->pid == pid) if (ctl->pid == pid)
regs = ctl->regs_orig; regs = ctl->regs_orig;
else { else {
...@@ -242,8 +244,6 @@ static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl, ...@@ -242,8 +244,6 @@ static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl,
} }
memcpy(ctl->addr_cmd, &cmd, sizeof(cmd)); memcpy(ctl->addr_cmd, &cmd, sizeof(cmd));
if (args)
memcpy(ctl->addr_args, args, args_size);
parasite_setup_regs(ctl->parasite_ip, &regs); parasite_setup_regs(ctl->parasite_ip, &regs);
...@@ -251,9 +251,6 @@ static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl, ...@@ -251,9 +251,6 @@ static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl,
if (ret == 0) if (ret == 0)
ret = -(int)regs.ax; ret = -(int)regs.ax;
if (args)
memcpy(args, ctl->addr_args, args_size);
if (ret) if (ret)
pr_err("Parasite exited with %d\n", ret); pr_err("Parasite exited with %d\n", ret);
...@@ -266,10 +263,9 @@ static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl, ...@@ -266,10 +263,9 @@ static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl,
return ret; return ret;
} }
static int parasite_execute(unsigned int cmd, struct parasite_ctl *ctl, static int parasite_execute(unsigned int cmd, struct parasite_ctl *ctl)
void *args, int args_size)
{ {
return parasite_execute_by_pid(cmd, ctl, ctl->pid, args, args_size); return parasite_execute_by_pid(cmd, ctl, ctl->pid);
} }
static void *mmap_seized(struct parasite_ctl *ctl, static void *mmap_seized(struct parasite_ctl *ctl,
...@@ -360,15 +356,16 @@ static int parasite_prep_file(int fd, struct parasite_ctl *ctl) ...@@ -360,15 +356,16 @@ static int parasite_prep_file(int fd, struct parasite_ctl *ctl)
static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid) static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid)
{ {
int ret; int ret;
struct parasite_log_args a; struct parasite_log_args *a;
ret = parasite_send_fd(ctl, log_get_fd()); ret = parasite_send_fd(ctl, log_get_fd());
if (ret) if (ret)
return ret; return ret;
a.log_level = log_get_loglevel(); a = parasite_args(ctl, sizeof(*a));
a->log_level = log_get_loglevel();
ret = parasite_execute(PARASITE_CMD_CFG_LOG, ctl, &a, sizeof(a)); ret = parasite_execute(PARASITE_CMD_CFG_LOG, ctl);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -377,12 +374,14 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid) ...@@ -377,12 +374,14 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid)
static int parasite_init(struct parasite_ctl *ctl, pid_t pid) static int parasite_init(struct parasite_ctl *ctl, pid_t pid)
{ {
struct parasite_init_args args = { }; struct parasite_init_args *args;
static int sock = -1; static int sock = -1;
args = parasite_args(ctl, sizeof(*args));
pr_info("Putting tsock into pid %d\n", pid); pr_info("Putting tsock into pid %d\n", pid);
args.h_addr_len = gen_parasite_saddr(&args.h_addr, 0); args->h_addr_len = gen_parasite_saddr(&args->h_addr, 0);
args.p_addr_len = gen_parasite_saddr(&args.p_addr, pid); args->p_addr_len = gen_parasite_saddr(&args->p_addr, pid);
if (sock == -1) { if (sock == -1) {
int rst = -1; int rst = -1;
...@@ -400,7 +399,7 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid) ...@@ -400,7 +399,7 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid)
return -1; return -1;
} }
if (bind(sock, (struct sockaddr *)&args.h_addr, args.h_addr_len) < 0) { if (bind(sock, (struct sockaddr *)&args->h_addr, args->h_addr_len) < 0) {
pr_perror("Can't bind socket"); pr_perror("Can't bind socket");
goto err; goto err;
} }
...@@ -423,12 +422,12 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid) ...@@ -423,12 +422,12 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid)
} }
} }
if (parasite_execute(PARASITE_CMD_INIT, ctl, &args, sizeof(args)) < 0) { if (parasite_execute(PARASITE_CMD_INIT, ctl) < 0) {
pr_err("Can't init parasite\n"); pr_err("Can't init parasite\n");
goto err; goto err;
} }
if (connect(sock, (struct sockaddr *)&args.p_addr, args.p_addr_len) < 0) { if (connect(sock, (struct sockaddr *)&args->p_addr, args->p_addr_len) < 0) {
pr_perror("Can't connect a transport socket"); pr_perror("Can't connect a transport socket");
goto err; goto err;
} }
...@@ -443,25 +442,28 @@ err: ...@@ -443,25 +442,28 @@ err:
int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid, int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid,
unsigned int **tid_addr, pid_t *tid) unsigned int **tid_addr, pid_t *tid)
{ {
struct parasite_dump_tid_info args = { }; struct parasite_dump_tid_info *args;
int ret; int ret;
ret = parasite_execute_by_pid(PARASITE_CMD_DUMP_TID_ADDR, ctl, pid, args = parasite_args(ctl, sizeof(*args));
&args, sizeof(args));
ret = parasite_execute_by_pid(PARASITE_CMD_DUMP_TID_ADDR, ctl, pid);
*tid_addr = args.tid_addr; *tid_addr = args->tid_addr;
*tid = args.tid; *tid = args->tid;
return ret; return ret;
} }
int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset) int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
{ {
struct parasite_dump_sa_args args; struct parasite_dump_sa_args *args;
int ret, i, fd; int ret, i, fd;
SaEntry se = SA_ENTRY__INIT; SaEntry se = SA_ENTRY__INIT;
ret = parasite_execute(PARASITE_CMD_DUMP_SIGACTS, ctl, &args, sizeof(args)); args = parasite_args(ctl, sizeof(*args));
ret = parasite_execute(PARASITE_CMD_DUMP_SIGACTS, ctl);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -471,10 +473,10 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f ...@@ -471,10 +473,10 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
if (i == SIGSTOP || i == SIGKILL) if (i == SIGSTOP || i == SIGKILL)
continue; continue;
ASSIGN_TYPED(se.sigaction, args.sas[i].rt_sa_handler); ASSIGN_TYPED(se.sigaction, args->sas[i].rt_sa_handler);
ASSIGN_TYPED(se.flags, args.sas[i].rt_sa_flags); ASSIGN_TYPED(se.flags, args->sas[i].rt_sa_flags);
ASSIGN_TYPED(se.restorer, args.sas[i].rt_sa_restorer); ASSIGN_TYPED(se.restorer, args->sas[i].rt_sa_restorer);
ASSIGN_TYPED(se.mask, args.sas[i].rt_sa_mask.sig[0]); ASSIGN_TYPED(se.mask, args->sas[i].rt_sa_mask.sig[0]);
if (pb_write_one(fd, &se, PB_SIGACT) < 0) if (pb_write_one(fd, &se, PB_SIGACT) < 0)
return -1; return -1;
...@@ -497,28 +499,36 @@ static int dump_one_timer(struct itimerval *v, int fd) ...@@ -497,28 +499,36 @@ static int dump_one_timer(struct itimerval *v, int fd)
int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset) int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
{ {
struct parasite_dump_itimers_args args; struct parasite_dump_itimers_args *args;
int ret, fd; int ret, fd;
ret = parasite_execute(PARASITE_CMD_DUMP_ITIMERS, ctl, &args, sizeof(args)); args = parasite_args(ctl, sizeof(*args));
ret = parasite_execute(PARASITE_CMD_DUMP_ITIMERS, ctl);
if (ret < 0) if (ret < 0)
return ret; return ret;
fd = fdset_fd(cr_fdset, CR_FD_ITIMERS); fd = fdset_fd(cr_fdset, CR_FD_ITIMERS);
ret = dump_one_timer(&args.real, fd); ret = dump_one_timer(&args->real, fd);
if (!ret) if (!ret)
ret = dump_one_timer(&args.virt, fd); ret = dump_one_timer(&args->virt, fd);
if (!ret) if (!ret)
ret = dump_one_timer(&args.prof, fd); ret = dump_one_timer(&args->prof, fd);
return ret; return ret;
} }
int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *misc) int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *misc)
{ {
return parasite_execute(PARASITE_CMD_DUMP_MISC, ctl, struct parasite_dump_misc *ma;
misc, sizeof(struct parasite_dump_misc));
ma = parasite_args(ctl, sizeof(*ma));
if (parasite_execute(PARASITE_CMD_DUMP_MISC, ctl) < 0)
return -1;
*misc = *ma;
return 0;
} }
/* /*
...@@ -528,7 +538,7 @@ int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_mis ...@@ -528,7 +538,7 @@ int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_mis
int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_area_list, int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_area_list,
struct cr_fdset *cr_fdset) struct cr_fdset *cr_fdset)
{ {
struct parasite_dump_pages_args parasite_dumppages = { }; struct parasite_dump_pages_args *parasite_dumppages;
unsigned long nrpages_dumped = 0, nrpages_skipped = 0, nrpages_total = 0; unsigned long nrpages_dumped = 0, nrpages_skipped = 0, nrpages_total = 0;
struct vma_area *vma_area; struct vma_area *vma_area;
int ret = -1; int ret = -1;
...@@ -541,12 +551,14 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a ...@@ -541,12 +551,14 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
if (ret < 0) if (ret < 0)
goto out; goto out;
ret = parasite_execute(PARASITE_CMD_DUMPPAGES_INIT, ctl, NULL, 0); ret = parasite_execute(PARASITE_CMD_DUMPPAGES_INIT, ctl);
if (ret < 0) { if (ret < 0) {
pr_err("Dumping pages failed with %i\n", ret); pr_err("Dumping pages failed with %i\n", ret);
goto out; goto out;
} }
parasite_dumppages = parasite_args(ctl, sizeof(*parasite_dumppages));
list_for_each_entry(vma_area, vma_area_list, list) { list_for_each_entry(vma_area, vma_area_list, list) {
/* /*
...@@ -566,7 +578,7 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a ...@@ -566,7 +578,7 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
if (vma_area_is(vma_area, VMA_ANON_SHARED)) if (vma_area_is(vma_area, VMA_ANON_SHARED))
continue; continue;
parasite_dumppages.vma_entry = vma_area->vma; parasite_dumppages->vma_entry = vma_area->vma;
if (!vma_area_is(vma_area, VMA_ANON_PRIVATE) && if (!vma_area_is(vma_area, VMA_ANON_PRIVATE) &&
!vma_area_is(vma_area, VMA_FILE_PRIVATE)) { !vma_area_is(vma_area, VMA_FILE_PRIVATE)) {
...@@ -574,9 +586,7 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a ...@@ -574,9 +586,7 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
continue; continue;
} }
ret = parasite_execute(PARASITE_CMD_DUMPPAGES, ctl, ret = parasite_execute(PARASITE_CMD_DUMPPAGES, ctl);
&parasite_dumppages,
sizeof(parasite_dumppages));
if (ret) { if (ret) {
pr_err("Dumping pages failed with %d\n", ret); pr_err("Dumping pages failed with %d\n", ret);
goto out_fini; goto out_fini;
...@@ -584,13 +594,13 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a ...@@ -584,13 +594,13 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
pr_info("vma %lx-%lx dumped: %lu pages %lu skipped %lu total\n", pr_info("vma %lx-%lx dumped: %lu pages %lu skipped %lu total\n",
vma_area->vma.start, vma_area->vma.end, vma_area->vma.start, vma_area->vma.end,
parasite_dumppages.nrpages_dumped, parasite_dumppages->nrpages_dumped,
parasite_dumppages.nrpages_skipped, parasite_dumppages->nrpages_skipped,
parasite_dumppages.nrpages_total); parasite_dumppages->nrpages_total);
nrpages_dumped += parasite_dumppages.nrpages_dumped; nrpages_dumped += parasite_dumppages->nrpages_dumped;
nrpages_skipped += parasite_dumppages.nrpages_skipped; nrpages_skipped += parasite_dumppages->nrpages_skipped;
nrpages_total += parasite_dumppages.nrpages_total; nrpages_total += parasite_dumppages->nrpages_total;
} }
pr_info("\n"); pr_info("\n");
...@@ -599,7 +609,7 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a ...@@ -599,7 +609,7 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
ret = 0; ret = 0;
out_fini: out_fini:
parasite_execute(PARASITE_CMD_DUMPPAGES_FINI, ctl, NULL, 0); parasite_execute(PARASITE_CMD_DUMPPAGES_FINI, ctl);
out: out:
fchmod(fdset_fd(cr_fdset, CR_FD_PAGES), CR_FD_PERM); fchmod(fdset_fd(cr_fdset, CR_FD_PAGES), CR_FD_PERM);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
...@@ -610,10 +620,14 @@ out: ...@@ -610,10 +620,14 @@ out:
int parasite_drain_fds_seized(struct parasite_ctl *ctl, int parasite_drain_fds_seized(struct parasite_ctl *ctl,
struct parasite_drain_fd *dfds, int *lfds, struct fd_opts *opts) struct parasite_drain_fd *dfds, int *lfds, struct fd_opts *opts)
{ {
int ret = -1; int ret = -1, size;
struct parasite_drain_fd *args;
size = drain_fds_size(dfds);
args = parasite_args(ctl, size);
memcpy(args, dfds, size);
ret = parasite_execute(PARASITE_CMD_DRAIN_FDS, ctl, ret = parasite_execute(PARASITE_CMD_DRAIN_FDS, ctl);
dfds, drain_fds_size(dfds));
if (ret) { if (ret) {
pr_err("Parasite failed to drain descriptors\n"); pr_err("Parasite failed to drain descriptors\n");
goto err; goto err;
...@@ -633,7 +647,7 @@ int parasite_get_proc_fd_seized(struct parasite_ctl *ctl) ...@@ -633,7 +647,7 @@ int parasite_get_proc_fd_seized(struct parasite_ctl *ctl)
{ {
int ret = -1, fd; int ret = -1, fd;
ret = parasite_execute(PARASITE_CMD_GET_PROC_FD, ctl, NULL, 0); ret = parasite_execute(PARASITE_CMD_GET_PROC_FD, ctl);
if (ret) { if (ret) {
pr_err("Parasite failed to get proc fd\n"); pr_err("Parasite failed to get proc fd\n");
return ret; return ret;
...@@ -656,7 +670,7 @@ int parasite_cure_seized(struct parasite_ctl *ctl) ...@@ -656,7 +670,7 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
if (ctl->parasite_ip) { if (ctl->parasite_ip) {
ctl->signals_blocked = 0; ctl->signals_blocked = 0;
parasite_execute(PARASITE_CMD_FINI, ctl, NULL, 0); parasite_execute(PARASITE_CMD_FINI, ctl);
} }
if (ctl->remote_map) { if (ctl->remote_map) {
......
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