[CRIU] [PATCHv3 06/30] x86/restorer: add sigreturn to compat mode
Dmitry Safonov
dsafonov at virtuozzo.com
Tue Jun 28 12:23:59 PDT 2016
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 at openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov at 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(-)
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);
--
2.9.0
More information about the CRIU
mailing list