[PATCHv3,06/30] x86/restorer: add sigreturn to compat mode

Submitted by Dmitry Safonov on June 28, 2016, 7:23 p.m.

Details

Message ID 20160628192423.14943-7-dsafonov@virtuozzo.com
State Rejected
Series "x86 Compatible C/R, part 2"
Headers show

Commit Message

Dmitry Safonov June 28, 2016, 7:23 p.m.
Do pure 32-bit sigreturn.
Change code selector, do 0x80 rt_sigreturn.
We should have here remapped 32-bit vDSO, all should be fine.

Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
---
 criu/arch/aarch64/include/asm/restorer.h |  2 +-
 criu/arch/arm/include/asm/restorer.h     |  2 +-
 criu/arch/ppc64/include/asm/restorer.h   |  2 +-
 criu/arch/x86/include/asm/restorer.h     | 30 ++++++++++++++++++++++++++++--
 criu/pie/parasite.c                      |  2 +-
 criu/pie/restorer.c                      |  9 +++++----
 6 files changed, 37 insertions(+), 10 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/arch/aarch64/include/asm/restorer.h b/criu/arch/aarch64/include/asm/restorer.h
index 57ccfddcd103..9bf4268bb74e 100644
--- a/criu/arch/aarch64/include/asm/restorer.h
+++ b/criu/arch/aarch64/include/asm/restorer.h
@@ -38,7 +38,7 @@  struct rt_sigframe {
 };
 
 
-#define ARCH_RT_SIGRETURN(new_sp)						\
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)					\
 	asm volatile(								\
 			"mov sp, %0					\n"	\
 			"mov x8, #"__stringify(__NR_rt_sigreturn)"	\n"	\
diff --git a/criu/arch/arm/include/asm/restorer.h b/criu/arch/arm/include/asm/restorer.h
index 2da417206cc3..34c2783323ef 100644
--- a/criu/arch/arm/include/asm/restorer.h
+++ b/criu/arch/arm/include/asm/restorer.h
@@ -67,7 +67,7 @@  struct rt_sigframe {
 };
 
 
-#define ARCH_RT_SIGRETURN(new_sp)					\
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)				\
 	asm volatile(							\
 		     "mov %%sp, %0				    \n"	\
 		     "mov %%r7,  #"__stringify(__NR_rt_sigreturn)"  \n" \
diff --git a/criu/arch/ppc64/include/asm/restorer.h b/criu/arch/ppc64/include/asm/restorer.h
index d7e20ca7d83c..8c1473eb9b0a 100644
--- a/criu/arch/ppc64/include/asm/restorer.h
+++ b/criu/arch/ppc64/include/asm/restorer.h
@@ -48,7 +48,7 @@  struct rt_sigframe {
         char abigap[USER_REDZONE_SIZE];
 } __attribute__ ((aligned (16)));
 
-#define ARCH_RT_SIGRETURN(new_sp)				\
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)			\
         asm volatile(						\
 		"mr 1, %0 \n"					\
 		"li 0, "__stringify(__NR_rt_sigreturn)" \n"	\
diff --git a/criu/arch/x86/include/asm/restorer.h b/criu/arch/x86/include/asm/restorer.h
index 9c57512696fd..6ae4245bb800 100644
--- a/criu/arch/x86/include/asm/restorer.h
+++ b/criu/arch/x86/include/asm/restorer.h
@@ -4,6 +4,7 @@ 
 #include "asm/types.h"
 #include "asm/fpu.h"
 #include "images/core.pb-c.h"
+#include "syscall-codes.h"
 
 struct rt_sigcontext {
 	unsigned long			r8;
@@ -168,7 +169,9 @@  struct rt_sigframe {
  */
 #define RT_SIGFRAME_OFFSET(rt_sigframe)	((rt_sigframe->is_native) ? 8 : 4 )
 
-#define ARCH_RT_SIGRETURN(new_sp)					\
+#define USER32_CS		0x23
+
+#define ARCH_RT_SIGRETURN_NATIVE(new_sp)				\
 	asm volatile(							\
 		     "movq %0, %%rax				    \n"	\
 		     "movq %%rax, %%rsp				    \n"	\
@@ -178,6 +181,29 @@  struct rt_sigframe {
 		     : "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)             \
 	asm volatile(							\
@@ -226,7 +252,7 @@  struct rt_sigframe {
 		     : "memory")
 #else /* !CONFIG_X86_64 */
 
-#define ARCH_RT_SIGRETURN(new_sp)					\
+#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe)				\
 	asm volatile(							\
 		     "movl %0, %%eax				    \n"	\
 		     "movl %%eax, %%esp				    \n"	\
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index da47319d9356..b1856ea0c0e7 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -602,7 +602,7 @@  static int __parasite_daemon_wait_msg(struct ctl_msg *m)
 
 static noinline void fini_sigreturn(unsigned long new_sp)
 {
-	ARCH_RT_SIGRETURN(new_sp);
+	ARCH_RT_SIGRETURN(new_sp, sigframe);
 }
 
 static int fini()
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index 823073209d20..0eee36378344 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -429,9 +429,10 @@  static int restore_thread_common(struct thread_restore_args *args)
 	return 0;
 }
 
-static void noinline rst_sigreturn(unsigned long new_sp)
+static void noinline rst_sigreturn(unsigned long new_sp,
+		struct rt_sigframe *sigframe)
 {
-	ARCH_RT_SIGRETURN(new_sp);
+	ARCH_RT_SIGRETURN(new_sp, sigframe);
 }
 
 /*
@@ -490,7 +491,7 @@  long __export_restore_thread(struct thread_restore_args *args)
 	futex_dec_and_wake(&thread_inprogress);
 
 	new_sp = (long)rt_sigframe + RT_SIGFRAME_OFFSET(rt_sigframe);
-	rst_sigreturn(new_sp);
+	rst_sigreturn(new_sp, rt_sigframe);
 
 core_restore_end:
 	pr_err("Restorer abnormal termination for %ld\n", sys_getpid());
@@ -1496,7 +1497,7 @@  long __export_restore_task(struct task_restore_args *args)
 	 * pure assembly since we don't need any additional
 	 * code insns from gcc.
 	 */
-	rst_sigreturn(new_sp);
+	rst_sigreturn(new_sp, rt_sigframe);
 
 core_restore_end:
 	futex_abort_and_wake(&task_entries->nr_in_progress);