[Devel] [RFC PATCH 2/2] cr: s390: fill in the read/write routines

Serge E. Hallyn serue at us.ibm.com
Wed Jan 14 21:06:16 PST 2009


This gets a simple checkpoint/restart working on an s390x.

Signed-off-by: Serge E. Hallyn <serue at us.ibm.com>
---
 arch/s390/include/asm/checkpoint_hdr.h |   35 +++++++++-
 arch/s390/mm/checkpoint.c              |  110 +++++++++++++++++++++++++++++---
 2 files changed, 132 insertions(+), 13 deletions(-)

diff --git a/arch/s390/include/asm/checkpoint_hdr.h b/arch/s390/include/asm/checkpoint_hdr.h
index 81ca76f..2be5ced 100644
--- a/arch/s390/include/asm/checkpoint_hdr.h
+++ b/arch/s390/include/asm/checkpoint_hdr.h
@@ -34,19 +34,46 @@
 #endif
 
 struct cr_hdr_head_arch {
-	__u16 unimplemented;
+	__u64 unimplemented;
 };
 
 struct cr_hdr_thread {
-	__s16 unimplemented;
+	/* restart blocks */
+	__u64 unimplemented;
 };
 
+/*
+ * Notes
+ * NUM_GPRS defined in <asm/ptrace.h> to be 16
+ * NUM_FPRS defined in <asm/ptrace.h> to be 16
+ * NUM_APRS defined in <asm/ptrace.h> to be 16
+ */
 struct cr_hdr_cpu {
-	__u64 unimplemented;
+	psw_t psw;
+	unsigned long args[1];
+	s390_fp_regs fp_regs;
+	unsigned long gprs[NUM_GPRS];
+	unsigned long orig_gpr2;
+	unsigned short svcnr;
+	unsigned short ilc;
+	unsigned int acrs[NUM_ACRS];
+	unsigned long ksp;
+	unsigned long prot_addr;
+	unsigned int trap_no;
+	per_struct per_info;
+	unsigned long ieee_instruction_pointer;
+	unsigned long pfault_wait;
 };
 
 struct cr_hdr_mm_context {
-	__s16 unimplemented;
+#if 0
+	unsigned long asce_bits;
+	unsigned long asce_limit;
+	int noexec;
+	int has_pgste;
+	int alloc_pgste;
+#endif
+	unsigned long vdso_base;
 };
 
 #endif /* __ASM_S390_CKPT_HDR__H */
diff --git a/arch/s390/mm/checkpoint.c b/arch/s390/mm/checkpoint.c
index 7f7e0b1..b2d7841 100644
--- a/arch/s390/mm/checkpoint.c
+++ b/arch/s390/mm/checkpoint.c
@@ -35,6 +35,29 @@ int cr_write_thread(struct cr_ctx *ctx, struct task_struct *t)
 	return ret;
 }
 
+static void cr_save_cpu_regs(struct cr_hdr_cpu *hh, struct task_struct *t)
+{
+	struct thread_struct *thread = &t->thread;
+	struct pt_regs *regs = task_pt_regs(t);
+
+	memcpy(&hh->psw, &regs->psw, sizeof(psw_t));
+	hh->args[0] = regs->args[0];
+	hh->svcnr = regs->svcnr;
+	hh->ilc = regs->ilc;
+	memcpy(hh->gprs, regs->gprs, NUM_GPRS*sizeof(unsigned long));
+	hh->orig_gpr2 = regs->orig_gpr2;
+
+	memcpy(&hh->fp_regs, &thread->fp_regs, sizeof(s390_fp_regs));
+	memcpy(hh->acrs, thread->acrs, NUM_ACRS * sizeof(unsigned int));
+	hh->ksp = thread->ksp;
+	printk(KERN_NOTICE "%s: saving ksp as %lx\n", __func__, hh->ksp);
+	hh->prot_addr = thread->prot_addr;
+	hh->trap_no = thread->trap_no;
+	memcpy(&hh->per_info, &thread->per_info, sizeof(per_struct));
+	hh->ieee_instruction_pointer = thread->ieee_instruction_pointer;
+	hh->pfault_wait = thread->pfault_wait;
+}
+
 /* dump the cpu state and registers of a given task */
 int cr_write_cpu(struct cr_ctx *ctx, struct task_struct *t)
 {
@@ -46,7 +69,7 @@ int cr_write_cpu(struct cr_ctx *ctx, struct task_struct *t)
 	h.len = sizeof(*hh);
 	h.parent = task_pid_vnr(t);
 
-	hh->unimplemented = 0xdeadbeef;
+	cr_save_cpu_regs(hh, t);
 
 	ret = cr_write_obj(ctx, &h, hh);
 	cr_hbuf_put(ctx, sizeof(*hh));
@@ -87,16 +110,22 @@ int cr_write_mm_context(struct cr_ctx *ctx, struct mm_struct *mm, int parent)
 	h.len = sizeof(*hh);
 	h.parent = parent;
 
-	hh->unimplemented = 0xbeef;
+#if 1
+	hh->vdso_base = mm->context.vdso_base;
+#else
+	hh->asce_bits = mm->context.asce_bits;
+	hh->asce_limit = mm->context.asce_limit;
+	hh->noexec = mm->context.noexec;
+	hh->has_pgste = mm->context.has_pgste;
+	hh->alloc_pgste = mm->context.alloc_pgste;
+#endif
 
 	ret = cr_write_obj(ctx, &h, hh);
 	cr_hbuf_put(ctx, sizeof(*hh));
 
-	WARN_ON_ONCE(ret < 0);
 	if (ret < 0)
 		goto out;
 
-	/* FIXME: NFI. */
 	ret = 0;
 out:
 	return ret;
@@ -107,14 +136,64 @@ out:
 /* read the thread_struct into the current task */
 int cr_read_thread(struct cr_ctx *ctx)
 {
-	WARN_ON_ONCE(true);
-	return -ENOSYS;
+	struct cr_hdr_thread *hh = cr_hbuf_get(ctx, sizeof(*hh));
+	int parent, ret;
+
+	parent = cr_read_obj_type(ctx, hh, sizeof(*hh), CR_HDR_THREAD);
+	if (parent < 0) {
+		ret = parent;
+		goto out;
+	}
+
+	if (hh->unimplemented != 0xbeef) {
+		printk(KERN_NOTICE "Error: cr file corrupted\n");
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = 0;
+
+out:
+	cr_hbuf_put(ctx, sizeof(*hh));
+	return 0;
 }
 
 int cr_read_cpu(struct cr_ctx *ctx)
 {
-	WARN_ON_ONCE(true);
-	return -ENOSYS;
+	struct cr_hdr_cpu *hh = cr_hbuf_get(ctx, sizeof(*hh));
+	struct thread_struct *thread = &current->thread;
+	struct pt_regs *regs = task_pt_regs(current);
+	int parent, ret;
+
+	parent = cr_read_obj_type(ctx, hh, sizeof(*hh), CR_HDR_CPU);
+	if  (parent < 0) {
+		ret = parent;
+		goto out;
+	}
+	ret = 0;
+
+	//memcpy(&regs->psw, &hh->psw, sizeof(psw_t));
+	regs->psw.addr &= ~PSW_ADDR_INSN;
+	regs->psw.addr |= hh->psw.addr & PSW_ADDR_INSN;
+	regs->args[0] = hh->args[0];
+	regs->svcnr = hh->svcnr;
+	regs->ilc = hh->ilc;
+	memcpy(regs->gprs, hh->gprs, NUM_GPRS*sizeof(unsigned long));
+	regs->orig_gpr2 = hh->orig_gpr2;
+
+	memcpy(&thread->fp_regs, &hh->fp_regs, sizeof(s390_fp_regs));
+	memcpy(thread->acrs, hh->acrs, NUM_ACRS * sizeof(unsigned int));
+	printk(KERN_NOTICE "%s: orig task's ksp was %lx\n", __func__, thread->ksp);
+	thread->ksp = hh->ksp;
+	printk(KERN_NOTICE "%s: restoring ksp as %lx\n", __func__, hh->ksp);
+	thread->prot_addr = hh->prot_addr;
+	thread->trap_no = hh->trap_no;
+	memcpy(&thread->per_info, &hh->per_info, sizeof(per_struct));
+	thread->ieee_instruction_pointer = hh->ieee_instruction_pointer;
+	thread->pfault_wait = hh->pfault_wait;
+
+out:
+	cr_hbuf_put(ctx, sizeof(*hh));
+	return ret;
 }
 
 int cr_read_head_arch(struct cr_ctx *ctx)
@@ -128,6 +207,11 @@ int cr_read_head_arch(struct cr_ctx *ctx)
 		goto out;
 	} else if (parent != 0)
 		goto out;
+
+	if (hh->unimplemented != 0xbeef) {
+		printk(KERN_NOTICE "%s: checkpoint file corrupt\n", __func__);
+		ret = -EINVAL;
+	}
 out:
 	cr_hbuf_put(ctx, sizeof(*hh));
 	return ret;
@@ -146,7 +230,15 @@ int cr_read_mm_context(struct cr_ctx *ctx, struct mm_struct *mm, int rparent)
 	if (parent != rparent)
 		goto out;
 
-	WARN_ON_ONCE(hh->unimplemented != (__s16)0xbeef);
+#if 0
+	mm->context.asce_bits = hh->asce_bits;
+	mm->context.asce_limit = hh->asce_limit;
+	mm->context.noexec = hh->noexec;
+	mm->context.has_pgste = hh->has_pgste;
+	mm->context.alloc_pgste = hh->alloc_pgste;
+#endif
+	mm->context.vdso_base = hh->vdso_base;
+	ret = 0;
 out:
 	cr_hbuf_put(ctx, sizeof(*hh));
 	return ret;
-- 
1.6.1

_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers




More information about the Devel mailing list