[CRIU] [PATCH 14/22] restorer: introduced the multiarch support into the restorer.
Alexander Kartashov
alekskartashov at parallels.com
Thu Dec 27 01:51:05 EST 2012
* Introduced the macro RT_SIGFRAME_UC to access the user context of a sigframe.
* Introduced TLS restoration for ARM.
* Don't touch a VMA that lies outside the virtual address space area 0..TASK_SIZE,
because VM above TASK_SIZE is read-only but some areas are mapped on ARM
into the process address space.
* Introduced the macro SIGFRAME_OFFSET to tune the beginning of a sigframe
on different architectures.
Signed-off-by: Alexander Kartashov <alekskartashov at parallels.com>
---
arch/x86/include/asm/restorer.h | 4 ++++
include/restorer.h | 14 +++++++++-----
pie/restorer.c | 23 +++++++++++++++++++----
3 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/arch/x86/include/asm/restorer.h b/arch/x86/include/asm/restorer.h
index 1ccc93c..4518064 100644
--- a/arch/x86/include/asm/restorer.h
+++ b/arch/x86/include/asm/restorer.h
@@ -129,9 +129,13 @@ struct rt_sigframe {
: "r"(ret) \
: "memory")
+#define RT_SIGFRAME_UC(rt_sigframe) rt_sigframe->uc
+
int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r);
int restore_fpu(struct rt_sigframe *sigframe, struct thread_restore_args *args);
+static void __attribute__ ((unused)) restore_tls(u32 tls) { }
+
#endif
diff --git a/include/restorer.h b/include/restorer.h
index 7548ae1..3bb40b9 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -17,10 +17,6 @@
#include "../protobuf/creds.pb-c.h"
#include "../protobuf/core.pb-c.h"
-#ifndef CONFIG_X86_64
-# error Only x86-64 is supported
-#endif
-
struct task_restore_core_args;
struct thread_restore_args;
@@ -67,7 +63,10 @@ struct thread_restore_args {
struct restore_mem_zone mem_zone;
int pid;
- UserX86RegsEntry gpregs;
+ UserRegsEntry gpregs;
+
+ u32 tls;
+
u64 clear_tid_addr;
bool has_futex;
@@ -126,6 +125,7 @@ struct task_restore_core_args {
u64 mm_saved_auxv[AT_VECTOR_SIZE];
u32 mm_saved_auxv_size;
char comm[TASK_COMM_LEN];
+ uint32_t tls;
int *rst_tcp_socks;
int rst_tcp_socks_size;
@@ -199,4 +199,8 @@ find_shmem(struct shmems *shmems, unsigned long shmid)
(vma_entry_is(vma, VMA_ANON_PRIVATE) || \
vma_entry_is(vma, VMA_FILE_PRIVATE)))
+#define SIGFRAME_OFFSET 8
+
+#include "asm/memcpy_64.h"
+
#endif /* __CR_RESTORER_H__ */
diff --git a/pie/restorer.c b/pie/restorer.c
index 04e7ab5..a9b4448 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -156,7 +156,7 @@ static int restore_thread_common(struct rt_sigframe *sigframe,
}
if (args->has_blk_sigset)
- sigframe->uc.uc_sigmask.sig[0] = args->blk_sigset;
+ RT_SIGFRAME_UC(sigframe).uc_sigmask.sig[0] = args->blk_sigset;
restore_sched_info(&args->sp);
if (restore_fpu(sigframe, args))
@@ -189,6 +189,7 @@ long __export_restore_thread(struct thread_restore_args *args)
restore_creds(&args->ta->creds);
+ restore_tls(args->tls);
pr_info("%ld: Restored\n", sys_gettid());
@@ -197,7 +198,7 @@ long __export_restore_thread(struct thread_restore_args *args)
futex_dec_and_wake(&thread_inprogress);
- new_sp = (long)rt_sigframe + 8;
+ new_sp = (long)rt_sigframe + SIGFRAME_OFFSET;
ARCH_RT_SIGRETURN(new_sp);
core_restore_end:
@@ -399,6 +400,10 @@ long __export_restore_task(struct task_restore_core_args *args)
}
}
+ if (vma_entry->end >= TASK_SIZE) {
+ continue;
+ }
+
if (vma_entry->end > premmapped_end) {
if (vma_entry->start < premmapped_end)
addr = premmapped_end;
@@ -421,6 +426,10 @@ long __export_restore_task(struct task_restore_core_args *args)
if (!vma_priv(vma_entry))
continue;
+ if (vma_entry->end >= TASK_SIZE) {
+ continue;
+ }
+
if (vma_entry->start > vma_entry->shmid)
break;
@@ -438,6 +447,10 @@ long __export_restore_task(struct task_restore_core_args *args)
if (!vma_priv(vma_entry))
continue;
+ if (vma_entry->start > TASK_SIZE) {
+ continue;
+ }
+
if (vma_entry->start < vma_entry->shmid)
break;
@@ -684,14 +697,16 @@ long __export_restore_task(struct task_restore_core_args *args)
ret = sys_munmap(args->task_entries, TASK_ENTRIES_SIZE);
if (ret < 0) {
- ret = ((long)__LINE__ << 32) | -ret;
+ ret = ((long)__LINE__ << 16) | ((-ret) & 0xffff);
goto core_restore_failed;
}
+ restore_tls(args->tls);
+
/*
* Sigframe stack.
*/
- new_sp = (long)rt_sigframe + 8;
+ new_sp = (long)rt_sigframe + SIGFRAME_OFFSET;
/*
* Prepare the stack and call for sigreturn,
--
1.7.10.4
More information about the CRIU
mailing list