sigframe: Move sigframe-related code into sigframe.*

Submitted by Pavel Emelianov on Oct. 28, 2016, 1:56 p.m.

Details

Message ID 58135910.8050207@virtuozzo.com
State Superseded
Series "sigframe: Move sigframe-related code into sigframe.*"
Headers show

Commit Message

Pavel Emelianov Oct. 28, 2016, 1:56 p.m.
From: Cyrill Gorcunov <gorcunov@openvz.org>

There's a lot of code making sigframes for PIE spread all over the
asm/restorer.h and arch/crtools.c. This patch collects it all into
asm/sigframe.h and arch/sigframe.c for better modularity and for
the sake of compel.

The patch is huge, but it just moves the code around (making u32/u64
types conversions to uint32/64_t-s where appropriate).

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-and-ported-on-dev-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/arch/aarch64/Makefile               |   1 +
 criu/arch/aarch64/include/asm/restorer.h |  53 -------
 criu/arch/aarch64/include/asm/sigframe.h |  51 +++++++
 criu/arch/aarch64/sigframe.c             |   8 ++
 criu/arch/arm/Makefile                   |   1 +
 criu/arch/arm/include/asm/restorer.h     |  84 ------------
 criu/arch/arm/include/asm/sigframe.h     |  83 +++++++++++
 criu/arch/arm/sigframe.c                 |   8 ++
 criu/arch/ppc64/Makefile                 |   1 +
 criu/arch/ppc64/crtools.c                |  48 -------
 criu/arch/ppc64/include/asm/restorer.h   |  56 --------
 criu/arch/ppc64/include/asm/sigframe.h   |  74 ++++++++++
 criu/arch/ppc64/sigframe.c               |  48 +++++++
 criu/arch/x86/Makefile                   |   1 +
 criu/arch/x86/crtools.c                  |  24 ----
 criu/arch/x86/include/asm/restorer.h     | 208 ----------------------------
 criu/arch/x86/include/asm/sigframe.h     | 229 +++++++++++++++++++++++++++++++
 criu/arch/x86/sigframe.c                 |  32 +++++
 criu/cr-restore.c                        |   1 +
 criu/include/sigframe-common.h           |  62 +++++++++
 criu/include/sigframe.h                  |  43 +-----
 criu/parasite-syscall.c                  |   1 +
 22 files changed, 602 insertions(+), 515 deletions(-)
 create mode 100644 criu/arch/aarch64/include/asm/sigframe.h
 create mode 100644 criu/arch/aarch64/sigframe.c
 create mode 100644 criu/arch/arm/include/asm/sigframe.h
 create mode 100644 criu/arch/arm/sigframe.c
 create mode 100644 criu/arch/ppc64/include/asm/sigframe.h
 create mode 100644 criu/arch/ppc64/sigframe.c
 create mode 100644 criu/arch/x86/include/asm/sigframe.h
 create mode 100644 criu/arch/x86/sigframe.c
 create mode 100644 criu/include/sigframe-common.h

Patch hide | download patch | download mbox

diff --git a/criu/arch/aarch64/Makefile b/criu/arch/aarch64/Makefile
index c7e141e..e841049 100644
--- a/criu/arch/aarch64/Makefile
+++ b/criu/arch/aarch64/Makefile
@@ -8,3 +8,4 @@  ccflags-y		+= -iquote $(SRC_DIR)/compel/include
 
 obj-y			+= cpu.o
 obj-y			+= crtools.o
+obj-y			+= sigframe.o
diff --git a/criu/arch/aarch64/include/asm/restorer.h b/criu/arch/aarch64/include/asm/restorer.h
index 80f358c..e23ab11 100644
--- a/criu/arch/aarch64/include/asm/restorer.h
+++ b/criu/arch/aarch64/include/asm/restorer.h
@@ -7,46 +7,8 @@ 
 #include "asm/types.h"
 #include "images/core.pb-c.h"
 
-/* Copied from the kernel header arch/arm64/include/uapi/asm/sigcontext.h */
-
-#define FPSIMD_MAGIC    0x46508001
-
-typedef struct fpsimd_context fpu_state_t;
-
-
-struct aux_context {
-	struct fpsimd_context fpsimd;
-	/* additional context to be added before "end" */
-	struct _aarch64_ctx end;
-};
-
-
-// XXX: the idetifier rt_sigcontext is expected to be struct by the CRIU code
-#define rt_sigcontext sigcontext
-
-
 #include "sigframe.h"
 
-
-/* Copied from the kernel source arch/arm64/kernel/signal.c */
-
-struct rt_sigframe {
-	siginfo_t info;
-	struct ucontext uc;
-	u64 fp;
-	u64 lr;
-};
-
-
-#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)					\
-	asm volatile(								\
-			"mov sp, %0					\n"	\
-			"mov x8, #"__stringify(__NR_rt_sigreturn)"	\n"	\
-			"svc #0						\n"	\
-			:							\
-			: "r"(new_sp)						\
-			: "sp", "x8", "memory")
-
 #define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid,		\
 			     thread_args, clone_restore_fn)			\
 	asm volatile(								\
@@ -90,26 +52,11 @@  struct rt_sigframe {
 			: "sp", "x0", "memory")
 
 
-#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
-#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.pc)
-#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
-#define RT_SIGFRAME_AUX_CONTEXT(rt_sigframe)				\
-	((struct aux_context*)&(rt_sigframe)->uc.uc_mcontext.__reserved)
-#define RT_SIGFRAME_FPU(rt_sigframe)					\
-	(&RT_SIGFRAME_AUX_CONTEXT(rt_sigframe)->fpsimd)
-#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
 #define kdat_compat_sigreturn_test()			0
 
-
 int restore_gpregs(struct rt_sigframe *f, UserAarch64RegsEntry *r);
 int restore_nonsigframe_gpregs(UserAarch64RegsEntry *r);
 
-static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
-		struct rt_sigframe *rsigframe)
-{
-	return 0;
-}
-
 static inline void restore_tls(tls_t *ptls)
 {
 	asm("msr tpidr_el0, %0" : : "r" (*ptls));
diff --git a/criu/arch/aarch64/include/asm/sigframe.h b/criu/arch/aarch64/include/asm/sigframe.h
new file mode 100644
index 0000000..3e8d63f
--- /dev/null
+++ b/criu/arch/aarch64/include/asm/sigframe.h
@@ -0,0 +1,51 @@ 
+#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
+#define UAPI_COMPEL_ASM_SIGFRAME_H__
+
+#include <asm/sigcontext.h>
+#include <sys/ucontext.h>
+
+#include <stdint.h>
+
+/* Copied from the kernel header arch/arm64/include/uapi/asm/sigcontext.h */
+
+#define FPSIMD_MAGIC			0x46508001
+
+typedef struct fpsimd_context		fpu_state_t;
+
+struct aux_context {
+	struct fpsimd_context		fpsimd;
+	/* additional context to be added before "end" */
+	struct _aarch64_ctx		end;
+};
+
+// XXX: the idetifier rt_sigcontext is expected to be struct by the CRIU code
+#define rt_sigcontext			sigcontext
+
+#include "sigframe-common.h"
+
+/* Copied from the kernel source arch/arm64/kernel/signal.c */
+
+struct rt_sigframe {
+	siginfo_t			info;
+	struct ucontext			uc;
+	uint64_t			fp;
+	uint64_t			lr;
+};
+
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)					\
+	asm volatile(								\
+			"mov sp, %0					\n"	\
+			"mov x8, #"__stringify(__NR_rt_sigreturn)"	\n"	\
+			"svc #0						\n"	\
+			:							\
+			: "r"(new_sp)						\
+			: "sp", "x8", "memory")
+
+#define RT_SIGFRAME_UC(rt_sigframe)		(&rt_sigframe->uc)
+#define RT_SIGFRAME_REGIP(rt_sigframe)		((long unsigned int)(rt_sigframe)->uc.uc_mcontext.pc)
+#define RT_SIGFRAME_HAS_FPU(rt_sigframe)	(1)
+#define RT_SIGFRAME_AUX_CONTEXT(rt_sigframe)	((struct aux_context*)&(rt_sigframe)->uc.uc_mcontext.__reserved)
+#define RT_SIGFRAME_FPU(rt_sigframe)		(&RT_SIGFRAME_AUX_CONTEXT(rt_sigframe)->fpsimd)
+#define RT_SIGFRAME_OFFSET(rt_sigframe)		0
+
+#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
diff --git a/criu/arch/aarch64/sigframe.c b/criu/arch/aarch64/sigframe.c
new file mode 100644
index 0000000..63e6524
--- /dev/null
+++ b/criu/arch/aarch64/sigframe.c
@@ -0,0 +1,8 @@ 
+#include "asm/types.h"
+#include "asm/sigframe.h"
+
+int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
+			     struct rt_sigframe *rsigframe)
+{
+	return 0;
+}
diff --git a/criu/arch/arm/Makefile b/criu/arch/arm/Makefile
index 3ceedd7..697062d 100644
--- a/criu/arch/arm/Makefile
+++ b/criu/arch/arm/Makefile
@@ -8,3 +8,4 @@  ccflags-y		+= -iquote $(SRC_DIR)/compel/include
 
 obj-y			+= cpu.o
 obj-y			+= crtools.o
+obj-y			+= sigframe.o
diff --git a/criu/arch/arm/include/asm/restorer.h b/criu/arch/arm/include/asm/restorer.h
index 3053117..6a550b8 100644
--- a/criu/arch/arm/include/asm/restorer.h
+++ b/criu/arch/arm/include/asm/restorer.h
@@ -4,78 +4,8 @@ 
 #include "asm/types.h"
 #include "images/core.pb-c.h"
 
-/* Copied from the Linux kernel header arch/arm/include/asm/sigcontext.h */
-
-struct rt_sigcontext {
-	unsigned long trap_no;
-	unsigned long error_code;
-	unsigned long oldmask;
-	unsigned long arm_r0;
-	unsigned long arm_r1;
-	unsigned long arm_r2;
-	unsigned long arm_r3;
-	unsigned long arm_r4;
-	unsigned long arm_r5;
-	unsigned long arm_r6;
-	unsigned long arm_r7;
-	unsigned long arm_r8;
-	unsigned long arm_r9;
-	unsigned long arm_r10;
-	unsigned long arm_fp;
-	unsigned long arm_ip;
-	unsigned long arm_sp;
-	unsigned long arm_lr;
-	unsigned long arm_pc;
-	unsigned long arm_cpsr;
-	unsigned long fault_address;
-};
-
-/* Copied from the Linux kernel header arch/arm/include/asm/ucontext.h */
-
-#define VFP_MAGIC               0x56465001
-#define VFP_STORAGE_SIZE        sizeof(struct vfp_sigframe)
-
-struct vfp_sigframe {
-	unsigned long           magic;
-	unsigned long           size;
-	struct user_vfp         ufp;
-	struct user_vfp_exc     ufp_exc;
-};
-
-typedef struct vfp_sigframe fpu_state_t;
-
-struct aux_sigframe {
-	/*
-	struct crunch_sigframe  crunch;
-        struct iwmmxt_sigframe  iwmmxt;
-	*/
-
-	struct vfp_sigframe     vfp;
-	unsigned long           end_magic;
-} __attribute__((__aligned__(8)));
-
 #include "sigframe.h"
 
-struct sigframe {
-	struct rt_ucontext uc;
-	unsigned long retcode[2];
-};
-
-struct rt_sigframe {
-	struct rt_siginfo info;
-	struct sigframe sig;
-};
-
-
-#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)				\
-	asm volatile(							\
-		     "mov %%sp, %0				    \n"	\
-		     "mov %%r7,  #"__stringify(__NR_rt_sigreturn)"  \n" \
-		     "svc #0					    \n"	\
-		     :							\
-		     : "r"(new_sp)					\
-		     : "sp","memory")
-
 #define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid,	\
 			     thread_args, clone_restore_fn)		\
 	asm volatile(							\
@@ -123,26 +53,12 @@  struct rt_sigframe {
 		     : "memory")
 
 
-#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->sig.uc)
-#define RT_SIGFRAME_REGIP(rt_sigframe) (rt_sigframe)->sig.uc.uc_mcontext.arm_ip
-#define RT_SIGFRAME_HAS_FPU(rt_sigframe) 1
-#define RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe)				\
-	((struct aux_sigframe *)&(rt_sigframe)->sig.uc.uc_regspace)
-#define RT_SIGFRAME_FPU(rt_sigframe)					\
-	(&RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe)->vfp)
-#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
 #define kdat_compat_sigreturn_test()			0
 
 
 int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r);
 int restore_nonsigframe_gpregs(UserArmRegsEntry *r);
 
-static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
-		struct rt_sigframe *rsigframe)
-{
-	return 0;
-}
-
 static inline void restore_tls(tls_t *ptls) {
 	asm (
 	     "mov %%r7, #15  \n"
diff --git a/criu/arch/arm/include/asm/sigframe.h b/criu/arch/arm/include/asm/sigframe.h
new file mode 100644
index 0000000..d679f71
--- /dev/null
+++ b/criu/arch/arm/include/asm/sigframe.h
@@ -0,0 +1,83 @@ 
+#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
+#define UAPI_COMPEL_ASM_SIGFRAME_H__
+
+/* Copied from the Linux kernel header arch/arm/include/asm/sigcontext.h */
+
+struct rt_sigcontext {
+	unsigned long		trap_no;
+	unsigned long		error_code;
+	unsigned long		oldmask;
+	unsigned long		arm_r0;
+	unsigned long		arm_r1;
+	unsigned long		arm_r2;
+	unsigned long		arm_r3;
+	unsigned long		arm_r4;
+	unsigned long		arm_r5;
+	unsigned long		arm_r6;
+	unsigned long		arm_r7;
+	unsigned long		arm_r8;
+	unsigned long		arm_r9;
+	unsigned long		arm_r10;
+	unsigned long		arm_fp;
+	unsigned long		arm_ip;
+	unsigned long		arm_sp;
+	unsigned long		arm_lr;
+	unsigned long		arm_pc;
+	unsigned long		arm_cpsr;
+	unsigned long		fault_address;
+};
+
+/* Copied from the Linux kernel header arch/arm/include/asm/ucontext.h */
+
+#define VFP_MAGIC		0x56465001
+#define VFP_STORAGE_SIZE	sizeof(struct vfp_sigframe)
+
+struct vfp_sigframe {
+	unsigned long		magic;
+	unsigned long		size;
+	struct user_vfp		ufp;
+	struct user_vfp_exc	ufp_exc;
+};
+
+typedef struct vfp_sigframe	fpu_state_t;
+
+struct aux_sigframe {
+	/*
+	struct crunch_sigframe  crunch;
+	struct iwmmxt_sigframe  iwmmxt;
+	*/
+
+	struct vfp_sigframe	vfp;
+	unsigned long		end_magic;
+} __attribute__((aligned(8)));
+
+#include "sigframe-common.h"
+
+struct sigframe {
+	struct rt_ucontext	uc;
+	unsigned long		retcode[2];
+};
+
+struct rt_sigframe {
+	struct rt_siginfo	info;
+	struct sigframe		sig;
+};
+
+
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)				\
+	asm volatile(							\
+		     "mov %%sp, %0				    \n"	\
+		     "mov %%r7,  #"__stringify(__NR_rt_sigreturn)"  \n" \
+		     "svc #0					    \n"	\
+		     :							\
+		     : "r"(new_sp)					\
+		     : "sp","memory")
+
+#define RT_SIGFRAME_UC(rt_sigframe)		(&rt_sigframe->sig.uc)
+#define RT_SIGFRAME_REGIP(rt_sigframe)		(rt_sigframe)->sig.uc.uc_mcontext.arm_ip
+#define RT_SIGFRAME_HAS_FPU(rt_sigframe)	1
+#define RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe)	((struct aux_sigframe *)&(rt_sigframe)->sig.uc.uc_regspace)
+#define RT_SIGFRAME_FPU(rt_sigframe)		(&RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe)->vfp)
+#define RT_SIGFRAME_OFFSET(rt_sigframe)		0
+
+#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
diff --git a/criu/arch/arm/sigframe.c b/criu/arch/arm/sigframe.c
new file mode 100644
index 0000000..63e6524
--- /dev/null
+++ b/criu/arch/arm/sigframe.c
@@ -0,0 +1,8 @@ 
+#include "asm/types.h"
+#include "asm/sigframe.h"
+
+int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
+			     struct rt_sigframe *rsigframe)
+{
+	return 0;
+}
diff --git a/criu/arch/ppc64/Makefile b/criu/arch/ppc64/Makefile
index a7b2b7a..fda9436 100644
--- a/criu/arch/ppc64/Makefile
+++ b/criu/arch/ppc64/Makefile
@@ -7,3 +7,4 @@  ccflags-y		+= -iquote $(SRC_DIR)/compel/include
 
 obj-y			+= cpu.o
 obj-y			+= crtools.o
+obj-y			+= sigframe.o
diff --git a/criu/arch/ppc64/crtools.c b/criu/arch/ppc64/crtools.c
index dd631f4..a276019 100644
--- a/criu/arch/ppc64/crtools.c
+++ b/criu/arch/ppc64/crtools.c
@@ -22,14 +22,6 @@ 
 #include "images/core.pb-c.h"
 #include "images/creds.pb-c.h"
 
-#define MSR_TMA (1UL<<34)	/* bit 29 Trans Mem state: Transactional */
-#define MSR_TMS (1UL<<33)	/* bit 30 Trans Mem state: Suspended */
-#define MSR_TM  (1UL<<32)	/* bit 31 Trans Mem Available */
-#define MSR_VEC (1UL<<25)
-#define MSR_VSX (1UL<<23)
-
-#define MSR_TM_ACTIVE(x) ((((x) & MSR_TM) && ((x)&(MSR_TMA|MSR_TMS))) != 0)
-
 #ifndef NT_PPC_TM_SPR
 #define NT_PPC_TM_CGPR  0x108           /* TM checkpointed GPR Registers */
 #define NT_PPC_TM_CFPR  0x109           /* TM checkpointed FPR Registers */
@@ -792,46 +784,6 @@  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.
- */
-static inline void update_vregs(mcontext_t *lcontext, mcontext_t *rcontext)
-{
-	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);
-	}
-}
-
-int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
-			     struct rt_sigframe *rframe)
-{
-	uint64_t msr = frame->uc.uc_mcontext.gp_regs[PT_MSR];
-
-	update_vregs(&frame->uc.uc_mcontext, &rframe->uc.uc_mcontext);
-
-	/* Sanity check: If TM so uc_link should be set, otherwise not */
-	if (MSR_TM_ACTIVE(msr) ^ (!!(frame->uc.uc_link))) {
-		BUG();
-		return 1;
-	}
-
-	/* Updating the transactional state address if any */
-	if (frame->uc.uc_link) {
-		update_vregs(&frame->uc_transact.uc_mcontext,
-			     &rframe->uc_transact.uc_mcontext);
-		frame->uc.uc_link =  &rframe->uc_transact;
-	}
-
-	return 0;
-}
-
 int restore_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r)
 {
 	restore_gp_regs(&f->uc.uc_mcontext, r);
diff --git a/criu/arch/ppc64/include/asm/restorer.h b/criu/arch/ppc64/include/asm/restorer.h
index 7f7074c..afd00c5 100644
--- a/criu/arch/ppc64/include/asm/restorer.h
+++ b/criu/arch/ppc64/include/asm/restorer.h
@@ -6,62 +6,13 @@ 
 #include <asm/types.h>
 #include "asm/types.h"
 
-/*
- * sigcontext structure defined in file
- *	/usr/include/powerpc64le-linux-gnu/bits/sigcontext.h,
- * included from /usr/include/signal.h
- *
- * Kernel definition can be found in arch/powerpc/include/uapi/asm/sigcontext.h
- */
-#include <signal.h>
-
-// XXX: the idetifier rt_sigcontext is expected to be struct by the CRIU code
-#define rt_sigcontext sigcontext
-
 #include "sigframe.h"
-#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
-
-/* Copied from the Linux kernel header arch/powerpc/include/asm/ptrace.h */
-#define USER_REDZONE_SIZE       512
-
-/* Copied from the Linux kernel source file arch/powerpc/kernel/signal_64.c */
-#define TRAMP_SIZE      	6
-
-/*
- * ucontext defined in /usr/include/powerpc64le-linux-gnu/sys/ucontext.h
- */
-struct rt_sigframe {
-        /* sys_rt_sigreturn requires the ucontext be the first field */
-        struct ucontext uc;
-        struct ucontext uc_transact;  	/* Transactional state	 */
-        unsigned long _unused[2];
-        unsigned int tramp[TRAMP_SIZE];
-        struct rt_siginfo *pinfo;
-        void *puc;
-        struct rt_siginfo info;
-        /* New 64 bit little-endian ABI allows redzone of 512 bytes below sp */
-        char abigap[USER_REDZONE_SIZE];
-} __attribute__ ((aligned (16)));
-
-#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)			\
-        asm volatile(						\
-		"mr 1, %0 \n"					\
-		"li 0, "__stringify(__NR_rt_sigreturn)" \n"	\
-		"sc \n"						\
-		:						\
-		: "r"(new_sp)					\
-		: "1", "memory")
 
 /*
  * Clone trampoline
  *
  * See glibc sysdeps/powerpc/powerpc64/sysdep.h for FRAME_MIN_SIZE defines
  */
-#if _CALL_ELF != 2
-#error Only supporting ABIv2.
-#else
-#define FRAME_MIN_SIZE_PARM     96
-#endif
 #define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, 	\
 			     thread_args, clone_restore_fn)		\
 	asm volatile( 							\
@@ -96,10 +47,6 @@  struct rt_sigframe {
 		  "r"(&thread_args[i])		/* %6 */		\
 		: "memory","0","3","4","5","6","7","14","15")
 
-#define RT_SIGFRAME_UC(rt_sigframe) (&(rt_sigframe)->uc)
-#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.gp_regs[PT_NIP])
-#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
-#define RT_SIGFRAME_FPU(rt_sigframe) (&(rt_sigframe)->uc.uc_mcontext)
 #define kdat_compat_sigreturn_test()			0
 
 int restore_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r);
@@ -118,9 +65,6 @@  static inline int ptrace_flush_breakpoints(pid_t pid)
         return 0;
 }
 
-int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
-		struct rt_sigframe *rframe);
-
 /*
  * Defined in arch/ppc64/syscall-common-ppc64.S
  */
diff --git a/criu/arch/ppc64/include/asm/sigframe.h b/criu/arch/ppc64/include/asm/sigframe.h
new file mode 100644
index 0000000..498bf8a
--- /dev/null
+++ b/criu/arch/ppc64/include/asm/sigframe.h
@@ -0,0 +1,74 @@ 
+#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
+#define UAPI_COMPEL_ASM_SIGFRAME_H__
+
+#include <asm/ptrace.h>
+#include <asm/elf.h>
+#include <asm/types.h>
+
+/*
+ * sigcontext structure defined in file
+ *	/usr/include/powerpc64le-linux-gnu/bits/sigcontext.h,
+ * included from /usr/include/signal.h
+ *
+ * Kernel definition can be found in arch/powerpc/include/uapi/asm/sigcontext.h
+ */
+#include <signal.h>
+
+// XXX: the idetifier rt_sigcontext is expected to be struct by the CRIU code
+#define rt_sigcontext sigcontext
+
+#include "sigframe-common.h"
+
+#define RT_SIGFRAME_OFFSET(rt_sigframe)	0
+
+/* Copied from the Linux kernel header arch/powerpc/include/asm/ptrace.h */
+#define USER_REDZONE_SIZE		512
+
+/* Copied from the Linux kernel source file arch/powerpc/kernel/signal_64.c */
+#define TRAMP_SIZE			6
+
+/*
+ * ucontext defined in /usr/include/powerpc64le-linux-gnu/sys/ucontext.h
+ */
+struct rt_sigframe {
+        /* sys_rt_sigreturn requires the ucontext be the first field */
+        struct ucontext			uc;
+        struct ucontext			uc_transact; /* Transactional state	 */
+        unsigned long			_unused[2];
+        unsigned int			tramp[TRAMP_SIZE];
+        struct rt_siginfo		*pinfo;
+        void				*puc;
+        struct rt_siginfo		info;
+        /* New 64 bit little-endian ABI allows redzone of 512 bytes below sp */
+        char				abigap[USER_REDZONE_SIZE];
+} __attribute__((aligned(16)));
+
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)			\
+        asm volatile(						\
+		"mr 1, %0 \n"					\
+		"li 0, "__stringify(__NR_rt_sigreturn)" \n"	\
+		"sc \n"						\
+		:						\
+		: "r"(new_sp)					\
+		: "1", "memory")
+
+#if _CALL_ELF != 2
+# error Only supporting ABIv2.
+#else
+# define FRAME_MIN_SIZE_PARM		96
+#endif
+
+#define RT_SIGFRAME_UC(rt_sigframe)		(&(rt_sigframe)->uc)
+#define RT_SIGFRAME_REGIP(rt_sigframe)		((long unsigned int)(rt_sigframe)->uc.uc_mcontext.gp_regs[PT_NIP])
+#define RT_SIGFRAME_HAS_FPU(rt_sigframe)	(1)
+#define RT_SIGFRAME_FPU(rt_sigframe)		(&(rt_sigframe)->uc.uc_mcontext)
+
+#define MSR_TMA (1UL<<34)	/* bit 29 Trans Mem state: Transactional */
+#define MSR_TMS (1UL<<33)	/* bit 30 Trans Mem state: Suspended */
+#define MSR_TM  (1UL<<32)	/* bit 31 Trans Mem Available */
+#define MSR_VEC (1UL<<25)
+#define MSR_VSX (1UL<<23)
+
+#define MSR_TM_ACTIVE(x) ((((x) & MSR_TM) && ((x)&(MSR_TMA|MSR_TMS))) != 0)
+
+#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
diff --git a/criu/arch/ppc64/sigframe.c b/criu/arch/ppc64/sigframe.c
new file mode 100644
index 0000000..52fad2e
--- /dev/null
+++ b/criu/arch/ppc64/sigframe.c
@@ -0,0 +1,48 @@ 
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "asm/sigframe.h"
+#include "asm/types.h"
+
+#include "log.h"
+#include "common/bug.h"
+
+/*
+ * 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.
+ */
+static inline void update_vregs(mcontext_t *lcontext, mcontext_t *rcontext)
+{
+	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);
+	}
+}
+
+int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
+			     struct rt_sigframe *rframe)
+{
+	uint64_t msr = frame->uc.uc_mcontext.gp_regs[PT_MSR];
+
+	update_vregs(&frame->uc.uc_mcontext, &rframe->uc.uc_mcontext);
+
+	/* Sanity check: If TM so uc_link should be set, otherwise not */
+	if (MSR_TM_ACTIVE(msr) ^ (!!(frame->uc.uc_link))) {
+		BUG();
+		return 1;
+	}
+
+	/* Updating the transactional state address if any */
+	if (frame->uc.uc_link) {
+		update_vregs(&frame->uc_transact.uc_mcontext,
+			     &rframe->uc_transact.uc_mcontext);
+		frame->uc.uc_link =  &rframe->uc_transact;
+	}
+
+	return 0;
+}
diff --git a/criu/arch/x86/Makefile b/criu/arch/x86/Makefile
index 6076fcc..04a0cb3 100644
--- a/criu/arch/x86/Makefile
+++ b/criu/arch/x86/Makefile
@@ -11,6 +11,7 @@  asflags-y		+= -iquote $(obj)/include
 
 obj-y			+= cpu.o
 obj-y			+= crtools.o
+obj-y			+= sigframe.o
 ifeq ($(CONFIG_COMPAT),y)
         obj-y		+= sigaction_compat.o
         obj-y		+= call32.o
diff --git a/criu/arch/x86/crtools.c b/criu/arch/x86/crtools.c
index b106846..2b351f0 100644
--- a/criu/arch/x86/crtools.c
+++ b/criu/arch/x86/crtools.c
@@ -708,30 +708,6 @@  int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
 }
 #endif
 
-int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
-		struct rt_sigframe *rsigframe)
-{
-	/*
-	 * Use local sigframe to check native/compat type,
-	 * but set address for rsigframe.
-	 */
-	fpu_state_t *fpu_state = (sigframe->is_native) ?
-		&rsigframe->native.fpu_state :
-		&rsigframe->compat.fpu_state;
-	unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
-
-	if (sigframe->is_native && (addr % 64ul) == 0ul) {
-		sigframe->native.uc.uc_mcontext.fpstate = &fpu_state->xsave;
-	} else if (!sigframe->is_native && (addr % 32ul) == 0ul) {
-		sigframe->compat.uc.uc_mcontext.fpstate = (u32)addr;
-	} else {
-		pr_err("Unaligned address passed: %lx\n", addr);
-		return -1;
-	}
-
-	return 0;
-}
-
 /* Copied from the gdb header gdb/nat/x86-dregs.h */
 
 /* Debug registers' indices.  */
diff --git a/criu/arch/x86/include/asm/restorer.h b/criu/arch/x86/include/asm/restorer.h
index a10f3c9..a421e00 100644
--- a/criu/arch/x86/include/asm/restorer.h
+++ b/criu/arch/x86/include/asm/restorer.h
@@ -6,91 +6,8 @@ 
 #include "images/core.pb-c.h"
 #include "uapi/std/syscall-codes.h"
 
-struct rt_sigcontext {
-	unsigned long			r8;
-	unsigned long			r9;
-	unsigned long			r10;
-	unsigned long			r11;
-	unsigned long			r12;
-	unsigned long			r13;
-	unsigned long			r14;
-	unsigned long			r15;
-	unsigned long			rdi;
-	unsigned long			rsi;
-	unsigned long			rbp;
-	unsigned long			rbx;
-	unsigned long			rdx;
-	unsigned long			rax;
-	unsigned long			rcx;
-	unsigned long			rsp;
-	unsigned long			rip;
-	unsigned long			eflags;
-	unsigned short			cs;
-	unsigned short			gs;
-	unsigned short			fs;
-	unsigned short			ss;
-	unsigned long			err;
-	unsigned long			trapno;
-	unsigned long			oldmask;
-	unsigned long			cr2;
-	void				*fpstate;
-	unsigned long			reserved1[8];
-};
-
-struct rt_sigcontext_32 {
-	u32				gs;
-	u32				fs;
-	u32				es;
-	u32				ds;
-	u32				di;
-	u32				si;
-	u32				bp;
-	u32				sp;
-	u32				bx;
-	u32				dx;
-	u32				cx;
-	u32				ax;
-	u32				trapno;
-	u32				err;
-	u32				ip;
-	u32				cs;
-	u32				flags;
-	u32				sp_at_signal;
-	u32				ss;
-
-	u32				fpstate;
-	u32				oldmask;
-	u32				cr2;
-};
-
-#define SIGFRAME_MAX_OFFSET 8
-
 #include "sigframe.h"
 
-/*
- * XXX: move declarations to generic sigframe.h or sigframe-compat.h
- *      when (if) other architectures will support compatible C/R
- */
-
-typedef u32			compat_uptr_t;
-typedef u32			compat_size_t;
-typedef u32			compat_sigset_word;
-
-#define _COMPAT_NSIG		64
-#define _COMPAT_NSIG_BPW	32
-#define _COMPAT_NSIG_WORDS	(_COMPAT_NSIG / _COMPAT_NSIG_BPW)
-
-typedef struct {
-	compat_sigset_word	sig[_COMPAT_NSIG_WORDS];
-} compat_sigset_t;
-
-typedef struct compat_siginfo {
-	int	si_signo;
-	int	si_errno;
-	int	si_code;
-	int	_pad[128/sizeof(int) - 3];
-} compat_siginfo_t;
-
 #ifdef CONFIG_COMPAT
 static inline void __always_unused __check_compat_sigset_t(void)
 {
@@ -112,113 +29,7 @@  static inline int
 arch_compat_rt_sigaction(void *stack, int sig, void *act) { return -1; }
 #endif
 
-#ifdef CONFIG_X86_32
-# define rt_sigframe_ia32	rt_sigframe
-#endif
-
-typedef struct compat_sigaltstack {
-	compat_uptr_t		ss_sp;
-	int			ss_flags;
-	compat_size_t		ss_size;
-} compat_stack_t;
-
-struct ucontext_ia32 {
-	unsigned int		uc_flags;
-	unsigned int		uc_link;
-	compat_stack_t		uc_stack;
-	struct rt_sigcontext_32	uc_mcontext;
-	k_rtsigset_t		uc_sigmask; /* mask last for extensibility */
-};
-
-struct rt_sigframe_ia32 {
-	u32			pretcode;
-	s32			sig;
-	u32			pinfo;
-	u32			puc;
 #ifdef CONFIG_X86_64
-	compat_siginfo_t	info;
-#else
-	struct rt_siginfo	info;
-#endif
-	struct ucontext_ia32	uc;
-	char			retcode[8];
-
-	/* fp state follows here */
-	fpu_state_t		fpu_state;
-};
-
-#ifdef CONFIG_X86_64
-struct rt_sigframe_64 {
-	char			*pretcode;
-	struct rt_ucontext	uc;
-	struct rt_siginfo	info;
-
-	/* fp state follows here */
-	fpu_state_t		fpu_state;
-};
-
-struct rt_sigframe {
-	union {
-		struct rt_sigframe_ia32	compat;
-		struct rt_sigframe_64	native;
-	};
-	bool is_native;
-};
-
-#define RT_SIGFRAME_UC_SIGMASK(rt_sigframe) ((rt_sigframe->is_native) ?	\
-	(&rt_sigframe->native.uc.uc_sigmask) :				\
-	(&rt_sigframe->compat.uc.uc_sigmask))
-
-#define RT_SIGFRAME_REGIP(rt_sigframe) ((rt_sigframe->is_native) ?	\
-	(rt_sigframe)->native.uc.uc_mcontext.rip :			\
-	(rt_sigframe)->compat.uc.uc_mcontext.ip)
-
-#define RT_SIGFRAME_FPU(rt_sigframe)	((rt_sigframe->is_native) ?	\
-	(&(rt_sigframe)->native.fpu_state) : (&(rt_sigframe)->compat.fpu_state))
-#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (RT_SIGFRAME_FPU(rt_sigframe)->has_fpu)
-
-/*
- * Sigframe offset is different for native/compat tasks.
- * Offsets calculations one may see at kernel:
- * - compatible is in sys32_rt_sigreturn at arch/x86/ia32/ia32_signal.c
- * - native is in sys_rt_sigreturn at arch/x86/kernel/signal.c
- */
-#define RT_SIGFRAME_OFFSET(rt_sigframe)	((rt_sigframe->is_native) ? 8 : 4 )
-
-#define USER32_CS		0x23
-
-#define ARCH_RT_SIGRETURN_NATIVE(new_sp)				\
-	asm volatile(							\
-		     "movq %0, %%rax				    \n"	\
-		     "movq %%rax, %%rsp				    \n"	\
-		     "movl $"__stringify(__NR_rt_sigreturn)", %%eax \n" \
-		     "syscall					    \n"	\
-		     :							\
-		     : "r"(new_sp)					\
-		     : "rax","rsp","memory")
-
-#define ARCH_RT_SIGRETURN_COMPAT(new_sp)				\
-	asm volatile(							\
-		"pushq $"__stringify(USER32_CS)"		\n"	\
-		"pushq $1f					\n"	\
-		"lretq						\n"	\
-		"1:						\n"	\
-		".code32					\n"	\
-		"movl %%edi, %%esp				\n"	\
-		"movl $"__stringify(__NR32_rt_sigreturn)",%%eax	\n"	\
-		"int $0x80					\n"	\
-		".code64					\n"	\
-		:							\
-		: "rdi"(new_sp)						\
-		: "eax","esp","memory")
-
-#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)				\
-do {									\
-	if ((rt_sigframe)->is_native)					\
-		ARCH_RT_SIGRETURN_NATIVE(new_sp);			\
-	else								\
-		ARCH_RT_SIGRETURN_COMPAT(new_sp);			\
-} while (0)
 
 #define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid,      \
 			     thread_args, clone_restore_fn)             \
@@ -274,16 +85,6 @@  do {									\
 extern int kdat_compat_sigreturn_test(void);
 #else /* !CONFIG_X86_64 */
 
-#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)				\
-	asm volatile(							\
-		     "movl %0, %%eax				    \n"	\
-		     "movl %%eax, %%esp				    \n"	\
-		     "movl $"__stringify(__NR_rt_sigreturn)", %%eax \n" \
-		     "int $0x80					    \n"	\
-		     :							\
-		     : "r"(new_sp)					\
-		     : "eax","esp","memory")
-
 #define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid,      \
 			     thread_args, clone_restore_fn)             \
 	(void)ret;							\
@@ -302,12 +103,6 @@  extern int kdat_compat_sigreturn_test(void);
 		     : "r"(ret)					\
 		     : "memory")
 
-#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
-#define RT_SIGFRAME_OFFSET(rt_sigframe)	4
-#define RT_SIGFRAME_REGIP(rt_sigframe)					\
-	(unsigned long)(rt_sigframe)->uc.uc_mcontext.ip
-#define RT_SIGFRAME_FPU(rt_sigframe) (&(rt_sigframe)->fpu_state)
-#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (RT_SIGFRAME_FPU(rt_sigframe)->has_fpu)
 #define kdat_compat_sigreturn_test()			0
 #endif /* !CONFIG_X86_64 */
 
@@ -347,9 +142,6 @@  static inline void _setup_sas(struct rt_sigframe* sigframe, ThreadSasEntry *sas)
 int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r);
 int restore_nonsigframe_gpregs(UserX86RegsEntry *r);
 
-int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
-		struct rt_sigframe *rsigframe);
-
 int ptrace_set_breakpoint(pid_t pid, void *addr);
 int ptrace_flush_breakpoints(pid_t pid);
 
diff --git a/criu/arch/x86/include/asm/sigframe.h b/criu/arch/x86/include/asm/sigframe.h
new file mode 100644
index 0000000..65ffccb
--- /dev/null
+++ b/criu/arch/x86/include/asm/sigframe.h
@@ -0,0 +1,229 @@ 
+#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
+#define UAPI_COMPEL_ASM_SIGFRAME_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "asm/fpu.h"
+
+#define SIGFRAME_MAX_OFFSET 8
+
+struct rt_sigcontext {
+	unsigned long			r8;
+	unsigned long			r9;
+	unsigned long			r10;
+	unsigned long			r11;
+	unsigned long			r12;
+	unsigned long			r13;
+	unsigned long			r14;
+	unsigned long			r15;
+	unsigned long			rdi;
+	unsigned long			rsi;
+	unsigned long			rbp;
+	unsigned long			rbx;
+	unsigned long			rdx;
+	unsigned long			rax;
+	unsigned long			rcx;
+	unsigned long			rsp;
+	unsigned long			rip;
+	unsigned long			eflags;
+	unsigned short			cs;
+	unsigned short			gs;
+	unsigned short			fs;
+	unsigned short			ss;
+	unsigned long			err;
+	unsigned long			trapno;
+	unsigned long			oldmask;
+	unsigned long			cr2;
+	void				*fpstate;
+	unsigned long			reserved1[8];
+};
+
+struct rt_sigcontext_32 {
+	uint32_t			gs;
+	uint32_t			fs;
+	uint32_t			es;
+	uint32_t			ds;
+	uint32_t			di;
+	uint32_t			si;
+	uint32_t			bp;
+	uint32_t			sp;
+	uint32_t			bx;
+	uint32_t			dx;
+	uint32_t			cx;
+	uint32_t			ax;
+	uint32_t			trapno;
+	uint32_t			err;
+	uint32_t			ip;
+	uint32_t			cs;
+	uint32_t			flags;
+	uint32_t			sp_at_signal;
+	uint32_t			ss;
+
+	uint32_t			fpstate;
+	uint32_t			oldmask;
+	uint32_t			cr2;
+};
+
+#include "sigframe-common.h"
+
+/*
+ * XXX: move declarations to generic sigframe.h or sigframe-compat.h
+ *      when (if) other architectures will support compatible C/R
+ */
+
+typedef uint32_t			compat_uptr_t;
+typedef uint32_t			compat_size_t;
+typedef uint32_t			compat_sigset_word;
+
+#define _COMPAT_NSIG			64
+#define _COMPAT_NSIG_BPW		32
+#define _COMPAT_NSIG_WORDS		(_COMPAT_NSIG / _COMPAT_NSIG_BPW)
+
+typedef struct {
+	compat_sigset_word		sig[_COMPAT_NSIG_WORDS];
+} compat_sigset_t;
+
+typedef struct compat_siginfo {
+	int				si_signo;
+	int				si_errno;
+	int				si_code;
+	int				_pad[128/sizeof(int) - 3];
+} compat_siginfo_t;
+
+#ifdef CONFIG_X86_32
+# define rt_sigframe_ia32		rt_sigframe
+#endif
+
+typedef struct compat_sigaltstack {
+	compat_uptr_t			ss_sp;
+	int				ss_flags;
+	compat_size_t			ss_size;
+} compat_stack_t;
+
+struct ucontext_ia32 {
+	unsigned int			uc_flags;
+	unsigned int			uc_link;
+	compat_stack_t			uc_stack;
+	struct rt_sigcontext_32		uc_mcontext;
+	k_rtsigset_t			uc_sigmask; /* mask last for extensibility */
+};
+
+struct rt_sigframe_ia32 {
+	uint32_t			pretcode;
+	int32_t				sig;
+	uint32_t			pinfo;
+	uint32_t			puc;
+#ifdef CONFIG_X86_64
+	compat_siginfo_t		info;
+#else
+	struct rt_siginfo		info;
+#endif
+	struct ucontext_ia32		uc;
+	char				retcode[8];
+
+	/* fp state follows here */
+	fpu_state_t			fpu_state;
+};
+
+#ifdef CONFIG_X86_64
+struct rt_sigframe_64 {
+	char				*pretcode;
+	struct rt_ucontext		uc;
+	struct rt_siginfo		info;
+
+	/* fp state follows here */
+	fpu_state_t			fpu_state;
+};
+
+struct rt_sigframe {
+	union {
+		struct rt_sigframe_ia32	compat;
+		struct rt_sigframe_64	native;
+	};
+	bool				is_native;
+};
+
+#define RT_SIGFRAME_UC_SIGMASK(rt_sigframe)				\
+	((rt_sigframe->is_native)			?		\
+	(&rt_sigframe->native.uc.uc_sigmask)		:		\
+	(&rt_sigframe->compat.uc.uc_sigmask))
+
+#define RT_SIGFRAME_REGIP(rt_sigframe)					\
+	((rt_sigframe->is_native)			?		\
+	(rt_sigframe)->native.uc.uc_mcontext.rip	:		\
+	(rt_sigframe)->compat.uc.uc_mcontext.ip)
+
+#define RT_SIGFRAME_FPU(rt_sigframe)					\
+	((rt_sigframe->is_native)			?		\
+	(&(rt_sigframe)->native.fpu_state)		:		\
+	 (&(rt_sigframe)->compat.fpu_state))
+
+#define RT_SIGFRAME_HAS_FPU(rt_sigframe)	(RT_SIGFRAME_FPU(rt_sigframe)->has_fpu)
+
+/*
+ * Sigframe offset is different for native/compat tasks.
+ * Offsets calculations one may see at kernel:
+ * - compatible is in sys32_rt_sigreturn at arch/x86/ia32/ia32_signal.c
+ * - native is in sys_rt_sigreturn at arch/x86/kernel/signal.c
+ */
+#define RT_SIGFRAME_OFFSET(rt_sigframe)		((rt_sigframe->is_native) ? 8 : 4 )
+
+#define USER32_CS		0x23
+
+#define ARCH_RT_SIGRETURN_NATIVE(new_sp)				\
+	asm volatile(							\
+		     "movq %0, %%rax				    \n"	\
+		     "movq %%rax, %%rsp				    \n"	\
+		     "movl $"__stringify(__NR_rt_sigreturn)", %%eax \n" \
+		     "syscall					    \n"	\
+		     :							\
+		     : "r"(new_sp)					\
+		     : "rax","rsp","memory")
+
+#define ARCH_RT_SIGRETURN_COMPAT(new_sp)				\
+	asm volatile(							\
+		"pushq $"__stringify(USER32_CS)"		\n"	\
+		"pushq $1f					\n"	\
+		"lretq						\n"	\
+		"1:						\n"	\
+		".code32					\n"	\
+		"movl %%edi, %%esp				\n"	\
+		"movl $"__stringify(__NR32_rt_sigreturn)",%%eax	\n"	\
+		"int $0x80					\n"	\
+		".code64					\n"	\
+		:							\
+		: "rdi"(new_sp)						\
+		: "eax","esp","memory")
+
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)				\
+do {									\
+	if ((rt_sigframe)->is_native)					\
+		ARCH_RT_SIGRETURN_NATIVE(new_sp);			\
+	else								\
+		ARCH_RT_SIGRETURN_COMPAT(new_sp);			\
+} while (0)
+
+#else /* CONFIG_X86_64 */
+
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)				\
+	asm volatile(							\
+		     "movl %0, %%eax				    \n"	\
+		     "movl %%eax, %%esp				    \n"	\
+		     "movl $"__stringify(__NR_rt_sigreturn)", %%eax \n" \
+		     "int $0x80					    \n"	\
+		     :							\
+		     : "r"(new_sp)					\
+		     : "eax","esp","memory")
+
+#define RT_SIGFRAME_UC(rt_sigframe)		(&rt_sigframe->uc)
+#define RT_SIGFRAME_OFFSET(rt_sigframe)		4
+#define RT_SIGFRAME_REGIP(rt_sigframe)					\
+	(unsigned long)(rt_sigframe)->uc.uc_mcontext.ip
+#define RT_SIGFRAME_FPU(rt_sigframe)		(&(rt_sigframe)->fpu_state)
+#define RT_SIGFRAME_HAS_FPU(rt_sigframe)	(RT_SIGFRAME_FPU(rt_sigframe)->has_fpu)
+
+#endif /* CONFIG_X86_64 */
+
+
+#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
diff --git a/criu/arch/x86/sigframe.c b/criu/arch/x86/sigframe.c
new file mode 100644
index 0000000..4474782
--- /dev/null
+++ b/criu/arch/x86/sigframe.c
@@ -0,0 +1,32 @@ 
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "asm/sigframe.h"
+#include "asm/types.h"
+
+#include "log.h"
+
+int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
+			     struct rt_sigframe *rsigframe)
+{
+	/*
+	 * Use local sigframe to check native/compat type,
+	 * but set address for rsigframe.
+	 */
+	fpu_state_t *fpu_state = (sigframe->is_native) ?
+		&rsigframe->native.fpu_state :
+		&rsigframe->compat.fpu_state;
+	unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
+
+	if (sigframe->is_native && (addr % 64ul) == 0ul) {
+		sigframe->native.uc.uc_mcontext.fpstate = &fpu_state->xsave;
+	} else if (!sigframe->is_native && (addr % 32ul) == 0ul) {
+		sigframe->compat.uc.uc_mcontext.fpstate = (uint32_t)addr;
+	} else {
+		pr_err("Unaligned address passed: %lx (native %d)\n",
+		       addr, sigframe->is_native);
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 252cc91..3abdea8 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -75,6 +75,7 @@ 
 #include "seccomp.h"
 #include "fault-injection.h"
 #include "sk-queue.h"
+#include "sigframe.h"
 
 #include "parasite-syscall.h"
 #include "files-reg.h"
diff --git a/criu/include/sigframe-common.h b/criu/include/sigframe-common.h
new file mode 100644
index 0000000..9d5131c
--- /dev/null
+++ b/criu/include/sigframe-common.h
@@ -0,0 +1,62 @@ 
+/*
+ * Don't include it directly but use "arch-sigframe.h" instead.
+ */
+#ifndef UAPI_COMPEL_SIGFRAME_COMMON_H__
+#define UAPI_COMPEL_SIGFRAME_COMMON_H__
+
+#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
+# error "Direct inclusion is forbidden, use <compel/asm/sigframe.h> instead"
+#endif
+
+#include <signal.h>
+#include "uapi/std/asm/syscall-types.h"
+
+struct rt_sigframe;
+
+#ifndef SIGFRAME_MAX_OFFSET
+# define SIGFRAME_MAX_OFFSET		RT_SIGFRAME_OFFSET(0)
+#endif
+
+#define RESTORE_STACK_ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
+
+/* sigframe should be aligned on 64 byte for x86 and 8 bytes for arm */
+#define RESTORE_STACK_SIGFRAME		\
+	RESTORE_STACK_ALIGN(sizeof(struct rt_sigframe) + SIGFRAME_MAX_OFFSET, 64)
+
+#ifndef __ARCH_SI_PREAMBLE_SIZE
+# define __ARCH_SI_PREAMBLE_SIZE	(3 * sizeof(int))
+#endif
+
+#define SI_MAX_SIZE	128
+
+#ifndef SI_PAD_SIZE
+# define SI_PAD_SIZE			((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
+#endif
+
+typedef struct rt_siginfo {
+	int	si_signo;
+	int	si_errno;
+	int	si_code;
+	int	_pad[SI_PAD_SIZE];
+} rt_siginfo_t;
+
+typedef struct rt_sigaltstack {
+	void	*ss_sp;
+	int	ss_flags;
+	size_t	ss_size;
+} rt_stack_t;
+
+struct rt_ucontext {
+	unsigned long		uc_flags;
+	struct rt_ucontext	*uc_link;
+	rt_stack_t		uc_stack;
+	struct rt_sigcontext	uc_mcontext;
+	k_rtsigset_t		uc_sigmask;	/* mask last for extensibility */
+	int                     __unused[32 - (sizeof (k_rtsigset_t) / sizeof (int))];
+	unsigned long           uc_regspace[128] __attribute__((aligned(8)));
+};
+
+extern int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
+				    struct rt_sigframe *rframe);
+
+#endif /* UAPI_COMPEL_SIGFRAME_COMMON_H__ */
diff --git a/criu/include/sigframe.h b/criu/include/sigframe.h
index cee64e2..bdda222 100644
--- a/criu/include/sigframe.h
+++ b/criu/include/sigframe.h
@@ -5,50 +5,9 @@ 
 #ifndef __CR_SIGFRAME_H__
 #define __CR_SIGFRAME_H__
 
+#include "asm/sigframe.h"
 #include "images/core.pb-c.h"
 
-struct rt_sigframe;
-
-#ifndef SIGFRAME_MAX_OFFSET
-#define SIGFRAME_MAX_OFFSET RT_SIGFRAME_OFFSET(0)
-#endif
-
-/* sigframe should be aligned on 64 byte for x86 and 8 bytes for arm */
-#define RESTORE_STACK_SIGFRAME						\
-	ALIGN(sizeof(struct rt_sigframe) + SIGFRAME_MAX_OFFSET, 64)
-
-#ifndef __ARCH_SI_PREAMBLE_SIZE
-#define __ARCH_SI_PREAMBLE_SIZE	(3 * sizeof(int))
-#endif
-
-#define SI_MAX_SIZE	128
-#ifndef SI_PAD_SIZE
-#define SI_PAD_SIZE	((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
-#endif
-
-typedef struct rt_siginfo {
-	int	si_signo;
-	int	si_errno;
-	int	si_code;
-	int	_pad[SI_PAD_SIZE];
-} rt_siginfo_t;
-
-typedef struct rt_sigaltstack {
-	void	*ss_sp;
-	int	ss_flags;
-	size_t	ss_size;
-} rt_stack_t;
-
-struct rt_ucontext {
-	unsigned long		uc_flags;
-	struct rt_ucontext	*uc_link;
-	rt_stack_t		uc_stack;
-	struct rt_sigcontext	uc_mcontext;
-	k_rtsigset_t		uc_sigmask;	/* mask last for extensibility */
-	int                     __unused[32 - (sizeof (k_rtsigset_t) / sizeof (int))];
-	unsigned long           uc_regspace[128] __attribute__((__aligned__(8)));
-};
-
 extern int construct_sigframe(struct rt_sigframe *sigframe,
 			      struct rt_sigframe *rsigframe,
 			      k_rtsigset_t *blkset,
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index e5b1ba3..2fe6e87 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -32,6 +32,7 @@ 
 #include "fault-injection.h"
 #include "uapi/std/syscall-codes.h"
 #include "signal.h"
+#include "sigframe.h"
 
 #include <string.h>
 #include <stdlib.h>

Comments

Cyrill Gorcunov Oct. 28, 2016, 1:55 p.m.
On Fri, Oct 28, 2016 at 04:56:32PM +0300, Pavel Emelyanov wrote:
> From: Cyrill Gorcunov <gorcunov@openvz.org>
> 
> There's a lot of code making sigframes for PIE spread all over the
> asm/restorer.h and arch/crtools.c. This patch collects it all into
> asm/sigframe.h and arch/sigframe.c for better modularity and for
> the sake of compel.
> 
> The patch is huge, but it just moves the code around (making u32/u64
> types conversions to uint32/64_t-s where appropriate).
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> Signed-off-and-ported-on-dev-by: Pavel Emelyanov <xemul@virtuozzo.com>

Thank a huge for porting it back to criu-dev!