diff --git a/compel/arch/aarch64/src/lib/infect.c b/compel/arch/aarch64/src/lib/infect.c index 41600e091..166ec2363 100644 --- a/compel/arch/aarch64/src/lib/infect.c +++ b/compel/arch/aarch64/src/lib/infect.c @@ -140,6 +140,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) return true; } +int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s) +{ + long ret; + int err; + + err = compel_syscall(ctl, __NR_sigaltstack, + &ret, 0, (unsigned long)&s->uc.uc_stack, + 0, 0, 0, 0); + return err ? err : ret; +} + /* * Range for task size calculated from the following Linux kernel files: * arch/arm64/include/asm/memory.h diff --git a/compel/arch/arm/src/lib/infect.c b/compel/arch/arm/src/lib/infect.c index a78108dff..27d258bc3 100644 --- a/compel/arch/arm/src/lib/infect.c +++ b/compel/arch/arm/src/lib/infect.c @@ -160,6 +160,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) return true; } +int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s) +{ + long ret; + int err; + + err = compel_syscall(ctl, __NR_sigaltstack, + &ret, 0, (unsigned long)&s->sig.uc.uc_stack, + 0, 0, 0, 0); + return err ? err : ret; +} + /* * Range for task size calculated from the following Linux kernel files: * arch/arm/include/asm/memory.h diff --git a/compel/arch/ppc64/src/lib/infect.c b/compel/arch/ppc64/src/lib/infect.c index f3f1aacec..32175174b 100644 --- a/compel/arch/ppc64/src/lib/infect.c +++ b/compel/arch/ppc64/src/lib/infect.c @@ -442,6 +442,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) return true; } +int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s) +{ + long ret; + int err; + + err = compel_syscall(ctl, __NR_sigaltstack, + &ret, 0, (unsigned long)&s->uc.uc_stack, + 0, 0, 0, 0); + return err ? err : ret; +} + /* * Copied for the Linux kernel arch/powerpc/include/asm/processor.h * diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c index 84ff21b15..23a96df86 100644 --- a/compel/arch/x86/src/lib/infect.c +++ b/compel/arch/x86/src/lib/infect.c @@ -419,6 +419,21 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) return true; } +int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s) +{ + int native = compel_mode_native(ctl); + void *where = native ? + (void *)&s->native.uc.uc_stack : + (void *)&s->compat.uc.uc_stack; + long ret; + int err; + + err = compel_syscall(ctl, __NR(sigaltstack, !native), + &ret, 0, (unsigned long)where, + 0, 0, 0, 0); + return err ? err : ret; +} + /* Copied from the gdb header gdb/nat/x86-dregs.h */ /* Debug registers' indices. */ diff --git a/compel/include/infect-priv.h b/compel/include/infect-priv.h index 0f80895a7..00671e71f 100644 --- a/compel/include/infect-priv.h +++ b/compel/include/infect-priv.h @@ -59,6 +59,7 @@ extern void *remote_mmap(struct parasite_ctl *ctl, int flags, int fd, off_t offset); extern bool arch_can_dump_task(struct parasite_ctl *ctl); extern int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, void *arg); +extern int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s); extern int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs); diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c index c02425036..c34452fd6 100644 --- a/compel/src/lib/infect.c +++ b/compel/src/lib/infect.c @@ -894,6 +894,13 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l ctl->r_thread_stack = ctl->remote_map + p; } + ret = arch_fetch_sas(ctl, ctl->rsigframe); + if (ret) { + pr_err("Can't fetch sigaltstack for task %d (ret %d)", + ctl->rpid, ret); + goto err; + } + if (parasite_start_daemon(ctl)) goto err;