[CRIU] [PATCH] ppc64: Fix checkpoint --leave-running
Andrey Vagin
avagin at openvz.org
Wed Sep 9 09:17:40 PDT 2015
2015-09-08 12:43 GMT+03:00 Laurent Dufour <ldufour at linux.vnet.ibm.com>:
> The commit ba7435095417 which introduces support for Altivec and VSX
> support was breaking the checkpoint --leave-running.
>
> The root cause is that the address of the Altivec and VSX registers in the
> signal frame should be computed for the stack in the context of the
> checkpointed process.
>
> This patch fixes this issue through the sigreturn_prep_fpu_frame which is
> designed to update the signal frame based on the remote address.
>
> Fixes: ba7435095417 ("ppc64: Add Altivec and VSX support")
> Reported-by: Andrey Vagin <avagin at openvz.org>
> Signed-off-by: Laurent Dufour <ldufour at linux.vnet.ibm.com>
Tested-by: Andrew Vagin <avagin at openvz.org>
Thanks!
> ---
> arch/ppc64/crtools.c | 23 +++++++++++++++++++++++
> arch/ppc64/include/asm/restorer.h | 7 ++-----
> 2 files changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/arch/ppc64/crtools.c b/arch/ppc64/crtools.c
> index 7fcc076dcab8..c7e6606f10ac 100644
> --- a/arch/ppc64/crtools.c
> +++ b/arch/ppc64/crtools.c
> @@ -227,6 +227,7 @@ static int put_altivec_regs(mcontext_t *mc, UserPpc64VrstateEntry *vse)
> vrregset_t *v_regs = (vrregset_t *)(((unsigned long)mc->vmx_reserve + 15) & ~0xful);
>
> pr_debug("Restoring Altivec registers\n");
> +
> if (vse->n_vrregs != 33*2) {
> pr_err("Corrupted Altivec dump data");
> return -1;
> @@ -275,6 +276,8 @@ static int get_vsx_regs(pid_t pid, CoreEntry *core)
> return -1;
> }
>
> + pr_debug("Dumping VSX registers\n");
> +
> vse = xmalloc(sizeof(*vse));
> if (!vse)
> return -1;
> @@ -465,6 +468,26 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
> return ret;
> }
>
> +/*
> + * The signal frame has been built using local addresses. Since it has to be
> + * used in the context of the checkpointed process, the v_regs pointer in the
> + * signal frame must be updated to match the address in the remote stack.
> + */
> +int sigreturn_prep_fpu_frame(struct rt_sigframe *frame, mcontext_t *rcontext)
> +{
> + mcontext_t *lcontext = &frame->uc.uc_mcontext;
> +
> + if (lcontext->v_regs) {
> + uint64_t offset = (uint64_t)(lcontext->v_regs) - (uint64_t)lcontext;
> + lcontext->v_regs = (vrregset_t *)((uint64_t)rcontext + offset);
> +
> + pr_debug("Updated v_regs:%llx (rcontext:%llx)\n",
> + (unsigned long long) lcontext->v_regs,
> + (unsigned long long) rcontext);
> + }
> + return 0;
> +}
> +
> int restore_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r)
> {
> int i;
> diff --git a/arch/ppc64/include/asm/restorer.h b/arch/ppc64/include/asm/restorer.h
> index d4560f74cf29..e728f133535e 100644
> --- a/arch/ppc64/include/asm/restorer.h
> +++ b/arch/ppc64/include/asm/restorer.h
> @@ -122,11 +122,8 @@ static inline int ptrace_flush_breakpoints(pid_t pid)
> return 0;
> }
>
> -static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
> - mcontext_t *sigcontext)
> -{
> - return 0;
> -}
> +int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
> + mcontext_t *sigcontext);
>
> /*
> * Defined in arch/ppc64/syscall-common-ppc64.S
> --
> 1.9.1
>
More information about the CRIU
mailing list