[CRIU] [PATCH 4/4] arch: Split get and save of user_regs_t and user_fpregs_t

Pavel Emelyanov xemul at virtuozzo.com
Mon Sep 26 01:25:38 PDT 2016


Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/arch/aarch64/crtools.c |  28 +++++---
 criu/arch/arm/crtools.c     |  23 +++---
 criu/arch/ppc64/crtools.c   | 117 +++++++++++++++++--------------
 criu/arch/x86/crtools.c     | 165 ++++++++++++++++++++++++--------------------
 4 files changed, 187 insertions(+), 146 deletions(-)

diff --git a/criu/arch/aarch64/crtools.c b/criu/arch/aarch64/crtools.c
index 9e0bd99..b8c6893 100644
--- a/criu/arch/aarch64/crtools.c
+++ b/criu/arch/aarch64/crtools.c
@@ -78,14 +78,16 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 	return err;
 }
 
+static int save_task_regs(CoreEntry *core,
+		user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
 
-#define assign_reg(dst, src, e)		dst->e = (__typeof__(dst->e))(src).e
+#define assign_reg(dst, src, e)		dst->e = (__typeof__(dst->e))(src)->e
 
 int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 {
 	struct iovec iov;
 	user_fpregs_struct_t fpsimd;
-	int i, ret;
+	int ret;
 
 	pr_info("Dumping GP/FPU registers for %d\n", pid);
 
@@ -103,6 +105,15 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 		goto err;
 	}
 
+	ret = save_task_regs(core, &regs, &fpsimd);
+err:
+	return ret;
+}
+
+static int save_task_regs(CoreEntry *core,
+		user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
+{
+	int i;
 
 	// Save the Aarch64 CPU state
 	for (i = 0; i < 31; ++i)
@@ -115,16 +126,13 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 	// Save the FP/SIMD state
 	for (i = 0; i < 32; ++i)
 	{
-		core->ti_aarch64->fpsimd->vregs[2*i]     = fpsimd.vregs[i];
-		core->ti_aarch64->fpsimd->vregs[2*i + 1] = fpsimd.vregs[i] >> 64;
+		core->ti_aarch64->fpsimd->vregs[2*i]     = fpsimd->vregs[i];
+		core->ti_aarch64->fpsimd->vregs[2*i + 1] = fpsimd->vregs[i] >> 64;
 	}
 	assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpsr);
 	assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpcr);
 
-	ret = 0;
-
-err:
-	return ret;
+	return 0;
 }
 
 int arch_alloc_thread_info(CoreEntry *core)
@@ -191,8 +199,8 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
 	for (i = 0; i < 32; ++i)
 		fpsimd->vregs[i] =	(__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i] |
 					((__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i + 1] << 64);
-	assign_reg(fpsimd, *core->ti_aarch64->fpsimd, fpsr);
-	assign_reg(fpsimd, *core->ti_aarch64->fpsimd, fpcr);
+	assign_reg(fpsimd, core->ti_aarch64->fpsimd, fpsr);
+	assign_reg(fpsimd, core->ti_aarch64->fpsimd, fpcr);
 
 	fpsimd->head.magic = FPSIMD_MAGIC;
 	fpsimd->head.size = sizeof(*fpsimd);
diff --git a/criu/arch/arm/crtools.c b/criu/arch/arm/crtools.c
index 5325ff0..c3421b9 100644
--- a/criu/arch/arm/crtools.c
+++ b/criu/arch/arm/crtools.c
@@ -80,7 +80,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 	return err;
 }
 
-#define assign_reg(dst, src, e)		dst->e = (__typeof__(dst->e))src.ARM_##e
+static int save_task_regs(CoreEntry *core,
+		user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
+
+#define assign_reg(dst, src, e)		dst->e = (__typeof__(dst->e))((src)->ARM_##e)
 
 #define PTRACE_GETVFPREGS 27
 int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
@@ -112,7 +115,14 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 		}
 	}
 
+	ret = save_task_regs(core, &regs, &vfp);
+err:
+	return ret;
+}
 
+static int save_task_regs(CoreEntry *core,
+		user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
+{
 	// Save the ARM CPU state
 
 	assign_reg(core->ti_arm->gpregs, regs, r0);
@@ -132,18 +142,15 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 	assign_reg(core->ti_arm->gpregs, regs, lr);
 	assign_reg(core->ti_arm->gpregs, regs, pc);
 	assign_reg(core->ti_arm->gpregs, regs, cpsr);
-	core->ti_arm->gpregs->orig_r0 = regs.ARM_ORIG_r0;
+	core->ti_arm->gpregs->orig_r0 = regs->ARM_ORIG_r0;
 
 
 	// Save the VFP state
 
-	memcpy(CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, &vfp.fpregs, sizeof(vfp.fpregs));
-	CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr = vfp.fpscr;
+	memcpy(CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, &fpregs->fpregs, sizeof(fpregs->fpregs));
+	CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr = fpregs->fpscr;
 
-	ret = 0;
-
-err:
-	return ret;
+	return 0;
 }
 
 int arch_alloc_thread_info(CoreEntry *core)
diff --git a/criu/arch/ppc64/crtools.c b/criu/arch/ppc64/crtools.c
index 24b2550..5ae8657 100644
--- a/criu/arch/ppc64/crtools.c
+++ b/criu/arch/ppc64/crtools.c
@@ -501,14 +501,13 @@ static int put_tm_regs(struct rt_sigframe *f, UserPpc64TmRegsEntry *tme)
 	return 0;
 }
 
+static int save_task_regs(CoreEntry *core,
+		user_regs_struct_t *regs, user_fpregs_struct_t *fpregs);
+
 /****************************************************************************/
 int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 {
 	user_fpregs_struct_t fpregs;
-	UserPpc64RegsEntry *gpregs;
-	UserPpc64FpstateEntry **fpstate;
-	UserPpc64VrstateEntry **vrstate;
-	UserPpc64VsxstateEntry **vsxstate;
 	int ret;
 
 	pr_info("Dumping GP/FPU registers for %d\n", pid);
@@ -557,7 +556,50 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 	} else
 		fpregs.flags = 0;
 
-	if (fpregs.flags) {
+	if (get_fpu_regs(pid, &fpregs))
+		return -1;
+
+	ret = get_altivec_regs(pid, &fpregs);
+	if (ret < 0)
+		return -1;
+
+	if (ret == 1) {
+		/*
+		 * Force the MSR_VEC bit of the restored MSR otherwise the
+		 * kernel will not restore them from the signal frame.
+		 */
+
+		fpregs.flags |= 0x16;
+
+		/*
+		 * Save the VSX registers if Altivec registers are supported
+		 */
+		ret = get_vsx_regs(pid, &fpregs);
+		if (ret < 0)
+			return -1;
+
+		if (ret == 0) {
+			/*
+			 * Force the MSR_VSX bit of the restored MSR otherwise
+			 * the kernel will not restore them from the signal
+			 * frame.
+			 */
+			fpregs.flags |= 0x32;
+		}
+	}
+
+	return save_task_regs(core, &regs, &fpregs);
+}
+
+static int save_task_regs(CoreEntry *core,
+		user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
+{
+	UserPpc64RegsEntry *gpregs;
+	UserPpc64FpstateEntry **fpstate;
+	UserPpc64VrstateEntry **vrstate;
+	UserPpc64VsxstateEntry **vsxstate;
+
+	if (fpregs->flags) {
 		UserPpc64TmRegsEntry *tme;
 		tme = xmalloc(sizeof(*tme));
 		if (!tme)
@@ -575,28 +617,28 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 		gpregs = core->ti_ppc64->gpregs;
 
 		gpregs->has_tfhar 	= true;
-		gpregs->tfhar 		= fpregs.tm.tm_spr_regs.tfhar;
+		gpregs->tfhar 		= fpregs->tm.tm_spr_regs.tfhar;
 		gpregs->has_texasr 	= true;
-		gpregs->texasr		= fpregs.tm.tm_spr_regs.texasr;
+		gpregs->texasr		= fpregs->tm.tm_spr_regs.texasr;
 		gpregs->has_tfiar 	= true;
-		gpregs->tfiar		= fpregs.tm.tm_spr_regs.tfiar;
+		gpregs->tfiar		= fpregs->tm.tm_spr_regs.tfiar;
 
-		copy_gp_regs(gpregs, &fpregs.tm.regs);
+		copy_gp_regs(gpregs, &fpregs->tm.regs);
 
-		if (fpregs.flags & 0x2) {
-			core->ti_ppc64->fpstate = copy_fp_regs(fpregs.tm.fpregs);
+		if (fpregs->flags & 0x2) {
+			core->ti_ppc64->fpstate = copy_fp_regs(fpregs->tm.fpregs);
 			if (!core->ti_ppc64->fpstate)
 				return -1;
 		}
 
-		if (fpregs.flags & 0x4) {
-			core->ti_ppc64->vrstate = copy_altivec_regs((unsigned char *)fpregs.tm.vmxregs);
+		if (fpregs->flags & 0x4) {
+			core->ti_ppc64->vrstate = copy_altivec_regs((unsigned char *)fpregs->tm.vmxregs);
 			if (!core->ti_ppc64->vrstate)
 				return -1;
 		}
 
-		if (fpregs.flags & 0x8) {
-			core->ti_ppc64->vsxstate = copy_vsx_regs(fpregs.tm.vsxregs);
+		if (fpregs->flags & 0x8) {
+			core->ti_ppc64->vsxstate = copy_vsx_regs(fpregs->tm.vsxregs);
 			if (!core->ti_ppc64->vsxstate)
 				return -1;
 		}
@@ -612,47 +654,18 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 		vsxstate = &(core->ti_ppc64->vsxstate);
 	}
 
-	if (get_fpu_regs(pid, &fpregs))
-		return -1;
-
-	ret = get_altivec_regs(pid, &fpregs);
-	if (ret < 0)
-		return -1;
-
-	if (ret == 1) {
-		/*
-		 * Force the MSR_VEC bit of the restored MSR otherwise the
-		 * kernel will not restore them from the signal frame.
-		 */
-		gpregs->msr |= MSR_VEC;
-
-		/*
-		 * Save the VSX registers if Altivec registers are supported
-		 */
-		ret = get_vsx_regs(pid, &fpregs);
-		if (ret < 0)
-			return -1;
-
-		if (ret == 0) {
-			/*
-			 * Force the MSR_VSX bit of the restored MSR otherwise
-			 * the kernel will not restore them from the signal
-			 * frame.
-			 */
-			gpregs->msr |= MSR_VSX;
-		}
-	}
-
-	copy_gp_regs(gpregs, &regs);
-	*fpstate = copy_fp_regs(fpregs.fpregs);
+	copy_gp_regs(gpregs, regs);
+	*fpstate = copy_fp_regs(fpregs->fpregs);
 	if (!*fpstate)
 		return -1;
-	if (gpregs->msr & MSR_VEC) {
-		*vrstate = copy_altivec_regs(fpregs.vrregs);
+	if (fpregs->flags & 0x16) {
+		gpregs->msr |= MSR_VEC;
+		*vrstate = copy_altivec_regs(fpregs->vrregs);
 		if (!*vrstate)
 			return -1;
-		if (gpregs->msr & MSR_VSX) {
-			*vsxstate = copy_vsx_regs(fpregs.vsregs);
+		if (fpregs->flags & 0x32) {
+			gpregs->msr |= MSR_VSX;
+			*vsxstate = copy_vsx_regs(fpregs->vsregs);
 			if (!*vsxstate)
 				return -1;
 		}
diff --git a/criu/arch/x86/crtools.c b/criu/arch/x86/crtools.c
index d74efc3..9fee84a 100644
--- a/criu/arch/x86/crtools.c
+++ b/criu/arch/x86/crtools.c
@@ -193,10 +193,12 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 	((user_regs_native(pregs)) ? (int64_t)((pregs)->native.name) :	\
 				(int32_t)((pregs)->compat.name))
 
+static int save_task_regs(CoreEntry *core,
+		user_regs_struct_t *regs, user_fpregs_struct_t *fpregs);
+
 int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 {
-	user_fpregs_struct_t xsave	= {  };
-	UserX86RegsEntry *gpregs	= core->thread_info->gpregs;
+	user_fpregs_struct_t xsave	= {  }, *xs = NULL;
 
 	struct iovec iov;
 	int ret = -1;
@@ -221,60 +223,6 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 		}
 	}
 
-#define assign_reg(dst, src, e)		do { dst->e = (__typeof__(dst->e))src.e; } while (0)
-#define assign_array(dst, src, e)	memcpy(dst->e, &src.e, sizeof(src.e))
-
-	if (user_regs_native(&regs)) {
-		assign_reg(gpregs, regs.native, r15);
-		assign_reg(gpregs, regs.native, r14);
-		assign_reg(gpregs, regs.native, r13);
-		assign_reg(gpregs, regs.native, r12);
-		assign_reg(gpregs, regs.native, bp);
-		assign_reg(gpregs, regs.native, bx);
-		assign_reg(gpregs, regs.native, r11);
-		assign_reg(gpregs, regs.native, r10);
-		assign_reg(gpregs, regs.native, r9);
-		assign_reg(gpregs, regs.native, r8);
-		assign_reg(gpregs, regs.native, ax);
-		assign_reg(gpregs, regs.native, cx);
-		assign_reg(gpregs, regs.native, dx);
-		assign_reg(gpregs, regs.native, si);
-		assign_reg(gpregs, regs.native, di);
-		assign_reg(gpregs, regs.native, orig_ax);
-		assign_reg(gpregs, regs.native, ip);
-		assign_reg(gpregs, regs.native, cs);
-		assign_reg(gpregs, regs.native, flags);
-		assign_reg(gpregs, regs.native, sp);
-		assign_reg(gpregs, regs.native, ss);
-		assign_reg(gpregs, regs.native, fs_base);
-		assign_reg(gpregs, regs.native, gs_base);
-		assign_reg(gpregs, regs.native, ds);
-		assign_reg(gpregs, regs.native, es);
-		assign_reg(gpregs, regs.native, fs);
-		assign_reg(gpregs, regs.native, gs);
-		gpregs->mode = USER_X86_REGS_MODE__NATIVE;
-	} else {
-		assign_reg(gpregs, regs.compat, bx);
-		assign_reg(gpregs, regs.compat, cx);
-		assign_reg(gpregs, regs.compat, dx);
-		assign_reg(gpregs, regs.compat, si);
-		assign_reg(gpregs, regs.compat, di);
-		assign_reg(gpregs, regs.compat, bp);
-		assign_reg(gpregs, regs.compat, ax);
-		assign_reg(gpregs, regs.compat, ds);
-		assign_reg(gpregs, regs.compat, es);
-		assign_reg(gpregs, regs.compat, fs);
-		assign_reg(gpregs, regs.compat, gs);
-		assign_reg(gpregs, regs.compat, orig_ax);
-		assign_reg(gpregs, regs.compat, ip);
-		assign_reg(gpregs, regs.compat, cs);
-		assign_reg(gpregs, regs.compat, flags);
-		assign_reg(gpregs, regs.compat, sp);
-		assign_reg(gpregs, regs.compat, ss);
-		gpregs->mode = USER_X86_REGS_MODE__COMPAT;
-	}
-	gpregs->has_mode = true;
-
 #ifndef PTRACE_GETREGSET
 # define PTRACE_GETREGSET 0x4204
 #endif
@@ -304,37 +252,102 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
 		}
 	}
 
-	assign_reg(core->thread_info->fpregs, xsave.i387, cwd);
-	assign_reg(core->thread_info->fpregs, xsave.i387, swd);
-	assign_reg(core->thread_info->fpregs, xsave.i387, twd);
-	assign_reg(core->thread_info->fpregs, xsave.i387, fop);
-	assign_reg(core->thread_info->fpregs, xsave.i387, rip);
-	assign_reg(core->thread_info->fpregs, xsave.i387, rdp);
-	assign_reg(core->thread_info->fpregs, xsave.i387, mxcsr);
-	assign_reg(core->thread_info->fpregs, xsave.i387, mxcsr_mask);
+	xs = &xsave;
+out:
+	ret = save_task_regs(core, &regs, xs);
+err:
+	return ret;
+}
+
+static int save_task_regs(CoreEntry *core,
+		user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
+{
+	UserX86RegsEntry *gpregs	= core->thread_info->gpregs;
+
+#define assign_reg(dst, src, e)		do { dst->e = (__typeof__(dst->e))src.e; } while (0)
+#define assign_array(dst, src, e)	memcpy(dst->e, &src.e, sizeof(src.e))
+
+	if (user_regs_native(regs)) {
+		assign_reg(gpregs, regs->native, r15);
+		assign_reg(gpregs, regs->native, r14);
+		assign_reg(gpregs, regs->native, r13);
+		assign_reg(gpregs, regs->native, r12);
+		assign_reg(gpregs, regs->native, bp);
+		assign_reg(gpregs, regs->native, bx);
+		assign_reg(gpregs, regs->native, r11);
+		assign_reg(gpregs, regs->native, r10);
+		assign_reg(gpregs, regs->native, r9);
+		assign_reg(gpregs, regs->native, r8);
+		assign_reg(gpregs, regs->native, ax);
+		assign_reg(gpregs, regs->native, cx);
+		assign_reg(gpregs, regs->native, dx);
+		assign_reg(gpregs, regs->native, si);
+		assign_reg(gpregs, regs->native, di);
+		assign_reg(gpregs, regs->native, orig_ax);
+		assign_reg(gpregs, regs->native, ip);
+		assign_reg(gpregs, regs->native, cs);
+		assign_reg(gpregs, regs->native, flags);
+		assign_reg(gpregs, regs->native, sp);
+		assign_reg(gpregs, regs->native, ss);
+		assign_reg(gpregs, regs->native, fs_base);
+		assign_reg(gpregs, regs->native, gs_base);
+		assign_reg(gpregs, regs->native, ds);
+		assign_reg(gpregs, regs->native, es);
+		assign_reg(gpregs, regs->native, fs);
+		assign_reg(gpregs, regs->native, gs);
+		gpregs->mode = USER_X86_REGS_MODE__NATIVE;
+	} else {
+		assign_reg(gpregs, regs->compat, bx);
+		assign_reg(gpregs, regs->compat, cx);
+		assign_reg(gpregs, regs->compat, dx);
+		assign_reg(gpregs, regs->compat, si);
+		assign_reg(gpregs, regs->compat, di);
+		assign_reg(gpregs, regs->compat, bp);
+		assign_reg(gpregs, regs->compat, ax);
+		assign_reg(gpregs, regs->compat, ds);
+		assign_reg(gpregs, regs->compat, es);
+		assign_reg(gpregs, regs->compat, fs);
+		assign_reg(gpregs, regs->compat, gs);
+		assign_reg(gpregs, regs->compat, orig_ax);
+		assign_reg(gpregs, regs->compat, ip);
+		assign_reg(gpregs, regs->compat, cs);
+		assign_reg(gpregs, regs->compat, flags);
+		assign_reg(gpregs, regs->compat, sp);
+		assign_reg(gpregs, regs->compat, ss);
+		gpregs->mode = USER_X86_REGS_MODE__COMPAT;
+	}
+	gpregs->has_mode = true;
+
+	if (!fpregs)
+		return 0;
+
+	assign_reg(core->thread_info->fpregs, fpregs->i387, cwd);
+	assign_reg(core->thread_info->fpregs, fpregs->i387, swd);
+	assign_reg(core->thread_info->fpregs, fpregs->i387, twd);
+	assign_reg(core->thread_info->fpregs, fpregs->i387, fop);
+	assign_reg(core->thread_info->fpregs, fpregs->i387, rip);
+	assign_reg(core->thread_info->fpregs, fpregs->i387, rdp);
+	assign_reg(core->thread_info->fpregs, fpregs->i387, mxcsr);
+	assign_reg(core->thread_info->fpregs, fpregs->i387, mxcsr_mask);
 
 	/* Make sure we have enough space */
-	BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(xsave.i387.st_space));
-	BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(xsave.i387.xmm_space));
+	BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(fpregs->i387.st_space));
+	BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(fpregs->i387.xmm_space));
 
-	assign_array(core->thread_info->fpregs, xsave.i387, st_space);
-	assign_array(core->thread_info->fpregs, xsave.i387, xmm_space);
+	assign_array(core->thread_info->fpregs, fpregs->i387, st_space);
+	assign_array(core->thread_info->fpregs, fpregs->i387, xmm_space);
 
 	if (cpu_has_feature(X86_FEATURE_XSAVE)) {
-		BUG_ON(core->thread_info->fpregs->xsave->n_ymmh_space != ARRAY_SIZE(xsave.ymmh.ymmh_space));
+		BUG_ON(core->thread_info->fpregs->xsave->n_ymmh_space != ARRAY_SIZE(fpregs->ymmh.ymmh_space));
 
-		assign_reg(core->thread_info->fpregs->xsave, xsave.xsave_hdr, xstate_bv);
-		assign_array(core->thread_info->fpregs->xsave, xsave.ymmh, ymmh_space);
+		assign_reg(core->thread_info->fpregs->xsave, fpregs->xsave_hdr, xstate_bv);
+		assign_array(core->thread_info->fpregs->xsave, fpregs->ymmh, ymmh_space);
 	}
 
 #undef assign_reg
 #undef assign_array
 
-out:
-	ret = 0;
-
-err:
-	return ret;
+	return 0;
 }
 
 int ptrace_get_regs(pid_t pid, user_regs_struct_t *regs)
-- 
2.5.0



More information about the CRIU mailing list