[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