From: "Serge E. Hallyn" <serue@us.ibm.com>
To: Nathan Lynch <ntl@pobox.com>
Cc: containers@lists.osdl.org, linuxppc-dev@ozlabs.org
Subject: Re: [PATCH 1/3] powerpc: bare minimum checkpoint/restart implementation
Date: Thu, 29 Jan 2009 21:55:30 -0600 [thread overview]
Message-ID: <20090130035530.GA30595@us.ibm.com> (raw)
In-Reply-To: <1233182478-27113-2-git-send-email-ntl@pobox.com>
Quoting Nathan Lynch (ntl@pobox.com):
> The only thing of significance here is that the checkpointed task's
> pt_regs and fp state are saved and restored (see cr_write_cpu and
> cr_read_cpu); the rest of the code consists of dummy implementations
> of the APIs the arch needs to provide to the checkpoint/restart core.
>
> What works:
> * self and external checkpoint of simple (single thread, one open
> file) 32- and 64-bit processes on a ppc64 kernel
>
> What doesn't work:
> * restarting a 32-bit task from a 64-bit task and vice versa
>
> Untested:
> * ppc32 (but it builds)
>
> Signed-off-by: Nathan Lynch <ntl@pobox.com>
> ---
> arch/powerpc/include/asm/checkpoint_hdr.h | 40 +++++
> arch/powerpc/mm/Makefile | 1 +
> arch/powerpc/mm/checkpoint.c | 261 +++++++++++++++++++++++++++++
> 3 files changed, 302 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/include/asm/checkpoint_hdr.h
> create mode 100644 arch/powerpc/mm/checkpoint.c
>
> diff --git a/arch/powerpc/include/asm/checkpoint_hdr.h b/arch/powerpc/include/asm/checkpoint_hdr.h
> new file mode 100644
> index 0000000..752c53f
> --- /dev/null
> +++ b/arch/powerpc/include/asm/checkpoint_hdr.h
> @@ -0,0 +1,40 @@
> +#ifndef __ASM_PPC_CKPT_HDR_H
> +#define __ASM_PPC_CKPT_HDR_H
> +/*
> + * Checkpoint/restart - architecture specific headers ppc
> + *
> + * Copyright (C) 2008 Oren Laadan
> + *
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License. See the file COPYING in the main directory of the Linux
> + * distribution for more details.
> + */
> +
> +#include <linux/types.h>
> +#include <asm/ptrace.h>
> +#include <asm/mmu.h>
> +#include <asm/processor.h>
> +
> +struct cr_hdr_head_arch {
> + __u32 unimplemented;
> +};
> +
> +struct cr_hdr_thread {
> + __u32 unimplemented;
> +};
> +
> +struct cr_hdr_cpu {
> + struct pt_regs pt_regs;
> + /* relevant fields from thread_struct */
> + double fpr[32][TS_FPRWIDTH];
> + unsigned int fpscr;
> + int fpexc_mode;
> + /* unsigned int align_ctl; this is never updated? */
> + unsigned long dabr;
> +};
> +
> +struct cr_hdr_mm_context {
> + __u32 unimplemented;
> +};
> +
> +#endif /* __ASM_PPC_CKPT_HDR__H */
> diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
> index e7392b4..8a523a0 100644
> --- a/arch/powerpc/mm/Makefile
> +++ b/arch/powerpc/mm/Makefile
> @@ -24,3 +24,4 @@ obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
> obj-$(CONFIG_PPC_MM_SLICES) += slice.o
> obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
> obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o
> +obj-$(CONFIG_CHECKPOINT_RESTART) += checkpoint.o
> diff --git a/arch/powerpc/mm/checkpoint.c b/arch/powerpc/mm/checkpoint.c
> new file mode 100644
> index 0000000..8cdff24
> --- /dev/null
> +++ b/arch/powerpc/mm/checkpoint.c
> @@ -0,0 +1,261 @@
> +/*
> + * Checkpoint/restart - architecture specific support for powerpc.
> + * Based on x86 implementation.
> + *
> + * Copyright (C) 2008 Oren Laadan
> + * Copyright 2009 IBM Corp.
> + *
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License. See the file COPYING in the main directory of the Linux
> + * distribution for more details.
> + */
> +
> +#define DEBUG 1 /* for pr_debug */
> +
> +#include <linux/checkpoint.h>
> +#include <linux/checkpoint_hdr.h>
> +#include <linux/kernel.h>
> +#include <asm/processor.h>
> +
> +static void cr_hdr_init(struct cr_hdr *hdr, __s16 type, __s16 len, __u32 parent)
> +{
> + hdr->type = type;
> + hdr->len = len;
> + hdr->parent = parent;
> +}
> +
> +/* dump the thread_struct of a given task */
> +int cr_write_thread(struct cr_ctx *ctx, struct task_struct *t)
> +{
> + struct cr_hdr_thread *thread_hdr;
> + struct cr_hdr cr_hdr;
> + u32 parent;
> + int ret;
> +
> + thread_hdr = cr_hbuf_get(ctx, sizeof(*thread_hdr));
> + if (!thread_hdr)
> + return -ENOMEM;
> +
> + parent = task_pid_vnr(t);
> +
> + cr_hdr_init(&cr_hdr, CR_HDR_THREAD, sizeof(*thread_hdr), parent);
All you're writing here is the vpid, right? The arch-independent
code already stores that?
> +
> + thread_hdr->unimplemented = 0xdeadbeef;
> +
> + ret = cr_write_obj(ctx, &cr_hdr, thread_hdr);
> + cr_hbuf_put(ctx, sizeof(*thread_hdr));
> +
> + return ret;
> +}
> +
> +/* dump the cpu state and registers of a given task */
> +int cr_write_cpu(struct cr_ctx *ctx, struct task_struct *t)
> +{
> + struct cr_hdr_cpu *cpu_hdr;
> + struct pt_regs *pt_regs;
> + struct cr_hdr cr_hdr;
> + u32 parent;
> + int ret;
> +
> + cpu_hdr = cr_hbuf_get(ctx, sizeof(*cpu_hdr));
> + if (!cpu_hdr)
> + return -ENOMEM;
> +
> + parent = task_pid_vnr(t);
> +
> + cr_hdr_init(&cr_hdr, CR_HDR_CPU, sizeof(*cpu_hdr), parent);
> +
> + /* pt_regs: GPRs, MSR, etc */
> + pt_regs = task_pt_regs(t);
> + cpu_hdr->pt_regs = *pt_regs;
> +
> + /* FP state */
> + memcpy(cpu_hdr->fpr, t->thread.fpr, sizeof(cpu_hdr->fpr));
> + cpu_hdr->fpscr = t->thread.fpscr.val;
> + cpu_hdr->fpexc_mode = t->thread.fpexc_mode;
> +
> + /* Handle DABR for now, dbcr[01] later */
> + cpu_hdr->dabr = t->thread.dabr;
> +
> + /* ToDo: Altivec/VSX/SPE state */
> +
> + ret = cr_write_obj(ctx, &cr_hdr, cpu_hdr);
> + cr_hbuf_put(ctx, sizeof(*cpu_hdr));
> +
> + return ret;
> +}
> +
> +int cr_write_head_arch(struct cr_ctx *ctx)
> +{
> + struct cr_hdr_head_arch *arch_hdr;
> + struct cr_hdr cr_hdr;
> + int ret;
> +
> + arch_hdr = cr_hbuf_get(ctx, sizeof(*arch_hdr));
> + if (!arch_hdr)
> + return -ENOMEM;
> +
> + cr_hdr_init(&cr_hdr, CR_HDR_HEAD_ARCH, sizeof(*arch_hdr), 0);
> +
> + arch_hdr->unimplemented = 0xdeadbeef;
No need to write this just for the sake of writing something, imo.
> + ret = cr_write_obj(ctx, &cr_hdr, arch_hdr);
> + cr_hbuf_put(ctx, sizeof(*arch_hdr));
> +
> + return ret;
> +}
> +
> +/* dump the mm->context state */
> +int cr_write_mm_context(struct cr_ctx *ctx, struct mm_struct *mm, int parent)
> +{
> + struct cr_hdr_mm_context *mm_hdr;
> + struct cr_hdr cr_hdr;
> + size_t size;
> + int ret;
> +
> + size = sizeof(*mm_hdr);
> +
> + mm_hdr = cr_hbuf_get(ctx, size);
> + if (!mm_hdr)
> + return -ENOMEM;
> +
> + cr_hdr_init(&cr_hdr, CR_HDR_MM_CONTEXT, size, parent);
> +
> + mm_hdr->unimplemented = 0xdeadbeef;
Again
> + ret = cr_write_obj(ctx, &cr_hdr, mm_hdr);
> + cr_hbuf_put(ctx, size);
> +
> + return ret;
> +}
> +
> +/* restart APIs */
> +
> +/* read the thread_struct into the current task */
> +int cr_read_thread(struct cr_ctx *ctx)
> +{
> + struct cr_hdr_thread *thread_hdr;
> + int ret;
> +
> + thread_hdr = cr_hbuf_get(ctx, sizeof(*thread_hdr));
> + if (!thread_hdr)
> + return -ENOMEM;
> +
> + ret = cr_read_obj_type(ctx, thread_hdr, sizeof(*thread_hdr),
> + CR_HDR_THREAD);
> + if (ret < 0)
> + goto out;
> +
> + ret = 0;
> +
> + if (thread_hdr->unimplemented != 0xdeadbeef) {
> + pr_debug("%s: unexpected thread_hdr contents: 0x%lx\n",
> + __func__, (unsigned long)thread_hdr->unimplemented);
> + ret = -EINVAL;
> + }
DROP
> +out:
> + cr_hbuf_put(ctx, sizeof(*thread_hdr));
> + return ret;
> +}
> +
> +/* Based on the MSR value from a checkpoint image, produce an MSR
> + * value that is appropriate for the restored task. Right now we only
> + * check for MSR_SF (64-bit) for PPC64.
> + */
> +static unsigned long sanitize_msr(unsigned long msr_ckpt)
> +{
> +#ifdef CONFIG_PPC32
> + return MSR_USER;
> +#else
> + if (msr_ckpt & MSR_SF)
> + return MSR_USER64;
> + return MSR_USER32;
> +#endif
> +}
> +
> +int cr_read_cpu(struct cr_ctx *ctx)
> +{
> + struct cr_hdr_cpu *cpu_hdr;
> + struct pt_regs *regs;
> + int ret;
> +
> + cpu_hdr = cr_hbuf_get(ctx, sizeof(*cpu_hdr));
> + if (!cpu_hdr)
> + return -ENOMEM;
> +
> + ret = cr_read_obj_type(ctx, cpu_hdr, sizeof(*cpu_hdr),
> + CR_HDR_CPU);
> + if (ret < 0)
> + goto out;
> +
> + ret = 0;
> +
> + regs = task_pt_regs(current);
> + *regs = cpu_hdr->pt_regs;
> +
> + regs->msr = sanitize_msr(regs->msr);
> +
> + /* FP state */
> + memcpy(current->thread.fpr, cpu_hdr->fpr, sizeof(current->thread.fpr));
> + current->thread.fpscr.val = cpu_hdr->fpscr;
> + current->thread.fpexc_mode = cpu_hdr->fpexc_mode;
> +
> + /* debug registers */
> + current->thread.dabr = cpu_hdr->dabr;
> +out:
> + cr_hbuf_put(ctx, sizeof(*cpu_hdr));
> + return ret;
> +}
> +
> +int cr_read_head_arch(struct cr_ctx *ctx)
> +{
> + struct cr_hdr_head_arch *arch_hdr;
> + int ret;
> +
> + arch_hdr = cr_hbuf_get(ctx, sizeof(*arch_hdr));
> + if (!arch_hdr)
> + return -ENOMEM;
> +
> + ret = cr_read_obj_type(ctx, arch_hdr, sizeof(*arch_hdr),
> + CR_HDR_HEAD_ARCH);
> + if (ret < 0)
> + goto out;
> +
> + ret = 0;
> +
> + if (arch_hdr->unimplemented != 0xdeadbeef) {
> + pr_debug("%s: unexpected arch_hdr contents: 0x%lx\n",
> + __func__, (unsigned long)arch_hdr->unimplemented);
> + ret = -EINVAL;
DROP
> + }
> +out:
> + cr_hbuf_put(ctx, sizeof(*arch_hdr));
> + return ret;
> +}
> +
> +int cr_read_mm_context(struct cr_ctx *ctx, struct mm_struct *mm, int rparent)
> +{
> + struct cr_hdr_mm_context *mm_hdr;
> + int ret;
> +
> + mm_hdr = cr_hbuf_get(ctx, sizeof(*mm_hdr));
> + if (!mm_hdr)
> + return -ENOMEM;
> +
> + ret = cr_read_obj_type(ctx, mm_hdr, sizeof(*mm_hdr),
> + CR_HDR_MM_CONTEXT);
> + if (ret != rparent)
> + goto out;
> +
> + ret = 0;
> +
> + if (mm_hdr->unimplemented != 0xdeadbeef) {
> + pr_debug("%s: unexpected mm_hdr contents: 0x%lx\n",
> + __func__, (unsigned long)mm_hdr->unimplemented);
> + ret = -EINVAL;
DROP
> + }
> +
> +out:
> + cr_hbuf_put(ctx, sizeof(*mm_hdr));
> + return ret;
> +}
> --
> 1.5.5
>
> _______________________________________________
> Containers mailing list
> Containers@lists.linux-foundation.org
> https://lists.linux-foundation.org/mailman/listinfo/containers
next prev parent reply other threads:[~2009-01-30 3:55 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-28 22:41 [RFC/PATCH 0/3] checkpoint/restart for powerpc Nathan Lynch
2009-01-28 22:41 ` [PATCH 3/3] allow checkpoint/restart on powerpc Nathan Lynch
[not found] ` <1233182478-27113-4-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
2009-01-30 4:10 ` Serge E. Hallyn
[not found] ` <1233182478-27113-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
2009-01-28 22:41 ` [PATCH 1/3] powerpc: bare minimum checkpoint/restart implementation Nathan Lynch
2009-01-28 22:41 ` Nathan Lynch
[not found] ` <1233182478-27113-2-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
2009-01-29 6:41 ` Oren Laadan
2009-01-29 6:41 ` Oren Laadan
2009-01-29 21:40 ` Nathan Lynch
2009-01-30 0:11 ` Oren Laadan
2009-01-30 0:11 ` Oren Laadan
2009-01-30 0:11 ` Oren Laadan
[not found] ` <49824599.5030503-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
2009-01-30 20:25 ` Nathan Lynch
2009-01-30 20:25 ` Nathan Lynch
2009-01-30 20:25 ` Nathan Lynch
2009-02-17 7:03 ` Nathan Lynch
[not found] ` <20090217010355.58afd5cf-4v5LP+xe+1byhTdZtsIeww@public.gmane.org>
2009-02-17 20:02 ` [PATCH 1/3 v2] powerpc: heckpoint/restart implementation Nathan Lynch
2009-02-17 20:02 ` Nathan Lynch
2009-03-13 3:31 ` [PATCH 1/3] powerpc: bare minimum checkpoint/restart implementation Oren Laadan
2009-03-13 3:31 ` Oren Laadan
[not found] ` <49B9D37A.1070503-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
2009-03-13 15:42 ` Cedric Le Goater
2009-03-13 15:42 ` Cedric Le Goater
2009-03-16 18:37 ` Nathan Lynch
2009-03-17 6:55 ` Cedric Le Goater
2009-03-18 9:15 ` Oren Laadan
2009-02-24 19:58 ` Serge E. Hallyn
2009-02-24 21:11 ` Nathan Lynch
[not found] ` <20090224151152.29e98b5f-4v5LP+xe+1byhTdZtsIeww@public.gmane.org>
2009-03-13 3:36 ` Oren Laadan
2009-03-13 3:36 ` Oren Laadan
2009-02-17 7:03 ` Nathan Lynch
2009-02-17 7:03 ` Nathan Lynch
2009-01-29 21:40 ` Nathan Lynch
[not found] ` <49814FA2.9060108-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
2009-01-29 21:40 ` Nathan Lynch
2009-01-30 4:01 ` Serge E. Hallyn
2009-01-30 4:01 ` Serge E. Hallyn
2009-01-30 4:01 ` Serge E. Hallyn
2009-01-30 3:55 ` Serge E. Hallyn
2009-02-04 3:39 ` Benjamin Herrenschmidt
2009-01-30 3:55 ` Serge E. Hallyn [this message]
2009-01-30 3:55 ` Serge E. Hallyn
2009-02-04 3:39 ` Benjamin Herrenschmidt
2009-02-04 15:54 ` Serge E. Hallyn
2009-02-04 15:54 ` Serge E. Hallyn
2009-02-04 20:58 ` Benjamin Herrenschmidt
[not found] ` <20090204155406.GA2039-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-02-04 20:58 ` Benjamin Herrenschmidt
2009-02-04 20:58 ` Benjamin Herrenschmidt
2009-02-04 23:44 ` Oren Laadan
[not found] ` <498A284E.4050501-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
2009-02-05 0:16 ` Benjamin Herrenschmidt
2009-02-05 0:16 ` Benjamin Herrenschmidt
2009-02-05 3:30 ` Oren Laadan
2009-02-05 3:30 ` Oren Laadan
2009-02-05 3:30 ` Oren Laadan
2009-02-05 16:09 ` Serge E. Hallyn
2009-02-05 16:09 ` Serge E. Hallyn
[not found] ` <20090205160946.GF27410-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-02-05 21:01 ` Benjamin Herrenschmidt
2009-02-05 21:01 ` Benjamin Herrenschmidt
2009-02-05 21:01 ` Benjamin Herrenschmidt
2009-02-05 16:09 ` Serge E. Hallyn
2009-02-05 0:16 ` Benjamin Herrenschmidt
2009-02-04 23:44 ` Oren Laadan
2009-02-04 23:44 ` Oren Laadan
2009-02-04 3:39 ` Benjamin Herrenschmidt
2009-01-28 22:41 ` [PATCH 2/3] powerpc: wire up checkpoint and restart syscalls Nathan Lynch
2009-01-28 22:41 ` Nathan Lynch
2009-01-28 22:41 ` [PATCH 3/3] allow checkpoint/restart on powerpc Nathan Lynch
2009-01-28 22:41 ` Nathan Lynch
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090130035530.GA30595@us.ibm.com \
--to=serue@us.ibm.com \
--cc=containers@lists.osdl.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=ntl@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.