[CRIU] [PATCH 01/20] x86: moved x86-specific files into the directory arch/x86.

alekskartashov at parallels.com alekskartashov at parallels.com
Wed Dec 12 09:48:38 EST 2012


From: Alexander Kartashov <alekskartashov at parallels.com>

The following files goes into the directory arch/x86 unmodified:

* include/atomic.h,
* include/linkage.h,
* include/memcpy_64.h,
* pie/parasite-head-x86-64.S,
* include/processor-flags.h,
* include/syscall-x86-64.def.

Removed target architecture checks from the files:

* include/image.h,
* include/syscall-types.h.

The following files are split into machine-independent (that goes into the directory arch/x86)
and machine-dependent parts:

* include/types.h --- machine dependent part is in the file arch/x86/arch-types.h,
* include/bitops.h --- machine dependent part is in the file arch/x86/arch_bitops.h.

The following files contain machine-dependent parts extracted from other sources:

* arch/x86/arch_parasite.h --- contains machine-dependent part of the parasite;
  it's empty now and intended only to support multiarch builds.
* arch/x86/arch_cr_dump.h --- contains machine-dependent parts of cr-dump.c.
* arch/x86/restorer_private.h --- contains machine-dependent parts of the restorer.
* arch/x86/arch_restorer.h --- contains machine-dependent parts of cr-restore.c.

Signed-off-by: Alexander Kartashov <alekskartashov at parallels.com>
---
 arch/x86/Makefile.inc                              |    7 +
 arch/x86/arch-types.h                              |   92 ++++++++++
 arch/x86/arch_bitops.h                             |   45 +++++
 arch/x86/arch_cr_dump.h                            |  163 ++++++++++++++++++
 arch/x86/arch_parasite.h                           |    6 +
 arch/x86/arch_parasite_syscall.h                   |   79 +++++++++
 arch/x86/arch_restorer.h                           |   18 ++
 {include => arch/x86}/atomic.h                     |    0
 {include => arch/x86}/linkage.h                    |    0
 {include => arch/x86}/memcpy_64.h                  |    0
 .../x86/parasite-head.S                            |    0
 {include => arch/x86}/processor-flags.h            |    0
 arch/x86/restorer_private.h                        |  179 ++++++++++++++++++++
 {include => arch/x86}/syscall-x86-64.def           |    0
 include/bitops.h                                   |   47 +----
 include/image.h                                    |   12 +-
 include/syscall-types.h                            |    4 -
 include/types.h                                    |   68 +-------
 18 files changed, 595 insertions(+), 125 deletions(-)
 create mode 100644 arch/x86/Makefile.inc
 create mode 100644 arch/x86/arch-types.h
 create mode 100644 arch/x86/arch_bitops.h
 create mode 100644 arch/x86/arch_cr_dump.h
 create mode 100644 arch/x86/arch_parasite.h
 create mode 100644 arch/x86/arch_parasite_syscall.h
 create mode 100644 arch/x86/arch_restorer.h
 rename {include => arch/x86}/atomic.h (100%)
 rename {include => arch/x86}/linkage.h (100%)
 rename {include => arch/x86}/memcpy_64.h (100%)
 rename pie/parasite-head-x86-64.S => arch/x86/parasite-head.S (100%)
 rename {include => arch/x86}/processor-flags.h (100%)
 create mode 100644 arch/x86/restorer_private.h
 rename {include => arch/x86}/syscall-x86-64.def (100%)

diff --git a/arch/x86/Makefile.inc b/arch/x86/Makefile.inc
new file mode 100644
index 0000000..b63bd25
--- /dev/null
+++ b/arch/x86/Makefile.inc
@@ -0,0 +1,7 @@
+DEFINES   += -DCONFIG_X86_64
+ARCH_BITS := 64
+
+CC 	 := gcc
+LD 	 := ld
+OBJCOPY	 := objcopy
+LDARCH	 := i386:x86-64
diff --git a/arch/x86/arch-types.h b/arch/x86/arch-types.h
new file mode 100644
index 0000000..ac99ee4
--- /dev/null
+++ b/arch/x86/arch-types.h
@@ -0,0 +1,92 @@
+#ifndef PROCESSOR_X86_64_H_
+#define PROCESSOR_X86_64_H_
+
+#define PRIs PRIu64
+
+typedef struct {
+	unsigned int	entry_number;
+	unsigned int	base_addr;
+	unsigned int	limit;
+	unsigned int	seg_32bit:1;
+	unsigned int	contents:2;
+	unsigned int	read_exec_only:1;
+	unsigned int	limit_in_pages:1;
+	unsigned int	seg_not_present:1;
+	unsigned int	useable:1;
+	unsigned int	lm:1;
+} user_desc_t;
+
+typedef struct {
+	unsigned long	r15;
+	unsigned long	r14;
+	unsigned long	r13;
+	unsigned long	r12;
+	unsigned long	bp;
+	unsigned long	bx;
+	unsigned long	r11;
+	unsigned long	r10;
+	unsigned long	r9;
+	unsigned long	r8;
+	unsigned long	ax;
+	unsigned long	cx;
+	unsigned long	dx;
+	unsigned long	si;
+	unsigned long	di;
+	unsigned long	orig_ax;
+	unsigned long	ip;
+	unsigned long	cs;
+	unsigned long	flags;
+	unsigned long	sp;
+	unsigned long	ss;
+	unsigned long	fs_base;
+	unsigned long	gs_base;
+	unsigned long	ds;
+	unsigned long	es;
+	unsigned long	fs;
+	unsigned long	gs;
+} user_regs_struct_t;
+
+#define REG_IP(regs)  regs.ip
+#define REG_RES(regs) regs.ax
+
+typedef struct {
+	unsigned short	cwd;
+	unsigned short	swd;
+	unsigned short	twd;	/* Note this is not the same as
+				   the 32bit/x87/FSAVE twd */
+	unsigned short	fop;
+	u64		rip;
+	u64		rdp;
+	u32		mxcsr;
+	u32		mxcsr_mask;
+	u32		st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
+	u32		xmm_space[64];	/* 16*16 bytes for each XMM-reg = 256 bytes */
+	u32		padding[24];
+} user_fpregs_struct_t;
+
+
+#define _NSIG_BPW 64
+#define TASK_SIZE (1UL << 47) - PAGE_SIZE
+
+#define CORE_ENTRY__MARCH CORE_ENTRY__MARCH__X86_64
+
+#define CORE_THREAD_INFO(core) core->thread_info
+#define CORE_GPREGS(core) (core->thread_info->gpregs)
+
+#ifdef CONFIG_X86_64
+# define AT_VECTOR_SIZE 44
+#else
+# define AT_VECTOR_SIZE 22		/* Not needed at moment */
+#endif
+
+typedef uint64_t auxv_t;
+
+#define SIGFRAME_OFFSET 8
+
+#define UserRegsEntry UserX86RegsEntry
+
+typedef struct {
+	int __unused;
+} UserFPState;
+
+#endif
diff --git a/arch/x86/arch_bitops.h b/arch/x86/arch_bitops.h
new file mode 100644
index 0000000..552b135
--- /dev/null
+++ b/arch/x86/arch_bitops.h
@@ -0,0 +1,45 @@
+#ifndef X86_64_BITOPS_H_
+#define X86_64_BITOPS_H_
+
+static inline void set_bit(int nr, volatile unsigned long *addr)
+{
+	asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
+}
+
+static inline void change_bit(int nr, volatile unsigned long *addr)
+{
+	asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
+}
+
+static inline int test_bit(int nr, volatile const unsigned long *addr)
+{
+	int oldbit;
+
+	asm volatile("bt %2,%1\n\t"
+		     "sbb %0,%0"
+		     : "=r" (oldbit)
+		     : "m" (*(unsigned long *)addr), "Ir" (nr));
+
+	return oldbit;
+}
+
+static inline void clear_bit(int nr, volatile unsigned long *addr)
+{
+	asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
+}
+
+/**
+ * __ffs - find first set bit in word
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+	asm("bsf %1,%0"
+		: "=r" (word)
+		: "rm" (word));
+	return word;
+}
+
+#endif
diff --git a/arch/x86/arch_cr_dump.h b/arch/x86/arch_cr_dump.h
new file mode 100644
index 0000000..a469f99
--- /dev/null
+++ b/arch/x86/arch_cr_dump.h
@@ -0,0 +1,163 @@
+#ifndef CR_DUMP_ARCH_H_X86_64_
+#define CR_DUMP_ARCH_H_X86_64_
+
+#define TI_SP(core) ((core)->thread_info->gpregs->sp)
+
+#define assign_reg(dst, src, e)		dst->e = (__typeof__(dst->e))src.e
+#define assign_array(dst, src, e)	memcpy(dst->e, &src.e, sizeof(src.e))
+
+static int get_task_regs(pid_t pid, CoreEntry *core, const struct parasite_ctl *ctl)
+{
+	user_fpregs_struct_t fpregs	= {-1};
+	user_regs_struct_t regs		= {-1};
+
+	int ret = -1;
+
+	pr_info("Dumping GP/FPU registers ... ");
+
+	if (ctl)
+		regs = ctl->regs_orig;
+	else {
+		if (ptrace(PTRACE_GETREGS, pid, NULL, &regs)) {
+			pr_err("Can't obtain GP registers for %d\n", pid);
+			goto err;
+		}
+	}
+
+	if (ptrace(PTRACE_GETFPREGS, pid, NULL, &fpregs)) {
+		pr_err("Can't obtain FPU registers for %d\n", pid);
+		goto err;
+	}
+
+	/* Did we come from a system call? */
+	if ((int)regs.orig_ax >= 0) {
+		/* Restart the system call */
+		switch ((long)(int)regs.ax) {
+		case -ERESTARTNOHAND:
+		case -ERESTARTSYS:
+		case -ERESTARTNOINTR:
+			regs.ax = regs.orig_ax;
+			regs.ip -= 2;
+			break;
+		case -ERESTART_RESTARTBLOCK:
+			regs.ax = __NR_restart_syscall;
+			regs.ip -= 2;
+			break;
+		}
+	}
+
+	assign_reg(core->thread_info->gpregs, regs, r15);
+	assign_reg(core->thread_info->gpregs, regs, r14);
+	assign_reg(core->thread_info->gpregs, regs, r13);
+	assign_reg(core->thread_info->gpregs, regs, r12);
+	assign_reg(core->thread_info->gpregs, regs, bp);
+	assign_reg(core->thread_info->gpregs, regs, bx);
+	assign_reg(core->thread_info->gpregs, regs, r11);
+	assign_reg(core->thread_info->gpregs, regs, r10);
+	assign_reg(core->thread_info->gpregs, regs, r9);
+	assign_reg(core->thread_info->gpregs, regs, r8);
+	assign_reg(core->thread_info->gpregs, regs, ax);
+	assign_reg(core->thread_info->gpregs, regs, cx);
+	assign_reg(core->thread_info->gpregs, regs, dx);
+	assign_reg(core->thread_info->gpregs, regs, si);
+	assign_reg(core->thread_info->gpregs, regs, di);
+	assign_reg(core->thread_info->gpregs, regs, orig_ax);
+	assign_reg(core->thread_info->gpregs, regs, ip);
+	assign_reg(core->thread_info->gpregs, regs, cs);
+	assign_reg(core->thread_info->gpregs, regs, flags);
+	assign_reg(core->thread_info->gpregs, regs, sp);
+	assign_reg(core->thread_info->gpregs, regs, ss);
+	assign_reg(core->thread_info->gpregs, regs, fs_base);
+	assign_reg(core->thread_info->gpregs, regs, gs_base);
+	assign_reg(core->thread_info->gpregs, regs, ds);
+	assign_reg(core->thread_info->gpregs, regs, es);
+	assign_reg(core->thread_info->gpregs, regs, fs);
+	assign_reg(core->thread_info->gpregs, regs, gs);
+
+	assign_reg(core->thread_info->fpregs, fpregs, cwd);
+	assign_reg(core->thread_info->fpregs, fpregs, swd);
+	assign_reg(core->thread_info->fpregs, fpregs, twd);
+	assign_reg(core->thread_info->fpregs, fpregs, fop);
+	assign_reg(core->thread_info->fpregs, fpregs, rip);
+	assign_reg(core->thread_info->fpregs, fpregs, rdp);
+	assign_reg(core->thread_info->fpregs, fpregs, mxcsr);
+	assign_reg(core->thread_info->fpregs, fpregs, mxcsr_mask);
+
+	/* Make sure we have enough space */
+	BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(fpregs.st_space));
+	BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(fpregs.xmm_space));
+	BUG_ON(core->thread_info->fpregs->n_padding != ARRAY_SIZE(fpregs.padding));
+
+	assign_array(core->thread_info->fpregs, fpregs,	st_space);
+	assign_array(core->thread_info->fpregs, fpregs,	xmm_space);
+	assign_array(core->thread_info->fpregs, fpregs,	padding);
+
+	ret = 0;
+
+err:
+	return ret;
+}
+
+
+static int arch_alloc_thread_info(CoreEntry *core) {
+	ThreadInfoX86 *thread_info;
+	UserX86RegsEntry *gpregs;
+	UserX86FpregsEntry *fpregs;
+
+	thread_info = xmalloc(sizeof(*thread_info));
+	if (!thread_info)
+		goto err;
+	thread_info_x86__init(thread_info);
+	core->thread_info = thread_info;
+
+	gpregs = xmalloc(sizeof(*gpregs));
+	if (!gpregs)
+		goto err;
+	user_x86_regs_entry__init(gpregs);
+	thread_info->gpregs = gpregs;
+
+	fpregs = xmalloc(sizeof(*fpregs));
+	if (!fpregs)
+		goto err;
+	user_x86_fpregs_entry__init(fpregs);
+	thread_info->fpregs = fpregs;
+
+	/* These are numbers from kernel */
+	fpregs->n_st_space	= 32;
+	fpregs->n_xmm_space	= 64;
+	fpregs->n_padding	= 24;
+
+	fpregs->st_space	= xzalloc(pb_repeated_size(fpregs, st_space));
+	fpregs->xmm_space	= xzalloc(pb_repeated_size(fpregs, xmm_space));
+	fpregs->padding		= xzalloc(pb_repeated_size(fpregs, padding));
+
+	if (!fpregs->st_space || !fpregs->xmm_space || !fpregs->padding)
+		goto err;
+
+	return 0;
+
+ err:
+	return 1;
+}
+
+
+static void core_entry_free(CoreEntry *core)
+{
+	if (core) {
+		if (CORE_THREAD_INFO(core)) {
+			if (CORE_THREAD_INFO(core)->fpregs) {
+				xfree(core->thread_info->fpregs->st_space);
+				xfree(core->thread_info->fpregs->xmm_space);
+				xfree(core->thread_info->fpregs->padding);
+			}
+			xfree(CORE_THREAD_INFO(core)->gpregs);
+			xfree(CORE_THREAD_INFO(core)->fpregs);
+		}
+		xfree(CORE_THREAD_INFO(core));
+		xfree(core->thread_core);
+		xfree(core->tc);
+		xfree(core->ids);
+	}
+}
+
+#endif
diff --git a/arch/x86/arch_parasite.h b/arch/x86/arch_parasite.h
new file mode 100644
index 0000000..c45b185
--- /dev/null
+++ b/arch/x86/arch_parasite.h
@@ -0,0 +1,6 @@
+#ifndef X86_64_PARASITE_H__
+#define X86_64_PARASITE_H__
+
+/* No x86_64 specific parasite code yet */
+
+#endif
diff --git a/arch/x86/arch_parasite_syscall.h b/arch/x86/arch_parasite_syscall.h
new file mode 100644
index 0000000..a272cea
--- /dev/null
+++ b/arch/x86/arch_parasite_syscall.h
@@ -0,0 +1,79 @@
+#ifndef X86_64_PARASITE_SYSCALL_H_
+#define X86_64_PARASITE_SYSCALL_H_
+
+#define ARCH_SI_TRAP SI_KERNEL
+
+static int __parasite_execute(struct parasite_ctl *ctl, pid_t pid, user_regs_struct_t *regs);
+
+/*
+ * Injected syscall instruction
+ */
+
+static const char code_syscall[] = {
+        0x0f, 0x05,                          /* syscall    */
+        0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc   /* int 3, ... */
+};
+
+
+/*
+ * The x86-64-specific parasite setup
+ */
+
+static void parasite_setup_regs(unsigned long new_ip, user_regs_struct_t *regs)
+{
+	regs->ip = new_ip;
+
+	/* Avoid end of syscall processing */
+	regs->orig_ax = -1;
+
+	/* Make sure flags are in known state */
+	regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_IF);
+}
+
+static void *mmap_seized(struct parasite_ctl *ctl,
+			 void *addr, size_t length, int prot,
+			 int flags, int fd, off_t offset)
+{
+	user_regs_struct_t regs = ctl->regs_orig;
+	void *map = NULL;
+	int ret;
+
+	regs.ax = (unsigned long)__NR_mmap;	/* mmap		*/
+	regs.di = (unsigned long)addr;		/* @addr	*/
+	regs.si = (unsigned long)length;	/* @length	*/
+	regs.dx = (unsigned long)prot;		/* @prot	*/
+	regs.r10= (unsigned long)flags;		/* @flags	*/
+	regs.r8 = (unsigned long)fd;		/* @fd		*/
+	regs.r9 = (unsigned long)offset;	/* @offset	*/
+
+	parasite_setup_regs(ctl->syscall_ip, &regs);
+
+	ret = __parasite_execute(ctl, ctl->pid, &regs);
+	if (ret)
+		goto err;
+
+	if ((long)regs.ax > 0)
+		map = (void *)regs.ax;
+err:
+	return map;
+}
+
+static int munmap_seized(struct parasite_ctl *ctl, void *addr, size_t length)
+{
+	user_regs_struct_t regs = ctl->regs_orig;
+	int ret;
+
+	regs.ax = (unsigned long)__NR_munmap;	/* mmap		*/
+	regs.di = (unsigned long)addr;		/* @addr	*/
+	regs.si = (unsigned long)length;	/* @length	*/
+
+	parasite_setup_regs(ctl->syscall_ip, &regs);
+
+	ret = __parasite_execute(ctl, ctl->pid, &regs);
+	if (!ret)
+		ret = (int)regs.ax;
+
+	return ret;
+}
+
+#endif
diff --git a/arch/x86/arch_restorer.h b/arch/x86/arch_restorer.h
new file mode 100644
index 0000000..7b87d9b
--- /dev/null
+++ b/arch/x86/arch_restorer.h
@@ -0,0 +1,18 @@
+#ifndef X86_64_RESTORER_H_
+#define X86_64_RESTORER_H_
+
+#define jump_to_restorer_blob(new_sp, restore_task_exec_start,          \
+			      task_args)				\
+	asm volatile(							\
+		     "movq %0, %%rbx				    \n" \
+		     "movq %1, %%rax				    \n" \
+		     "movq %2, %%rdi				    \n" \
+		     "movq %%rbx, %%rsp			       	    \n"	\
+		     "callq *%%rax				    \n" \
+		     :							\
+		     : "g"(new_sp),					\
+		       "g"(restore_task_exec_start),			\
+		       "g"(task_args)					\
+		     : "rsp", "rdi", "rsi", "rbx", "rax", "memory")
+
+#endif
diff --git a/include/atomic.h b/arch/x86/atomic.h
similarity index 100%
rename from include/atomic.h
rename to arch/x86/atomic.h
diff --git a/include/linkage.h b/arch/x86/linkage.h
similarity index 100%
rename from include/linkage.h
rename to arch/x86/linkage.h
diff --git a/include/memcpy_64.h b/arch/x86/memcpy_64.h
similarity index 100%
rename from include/memcpy_64.h
rename to arch/x86/memcpy_64.h
diff --git a/pie/parasite-head-x86-64.S b/arch/x86/parasite-head.S
similarity index 100%
rename from pie/parasite-head-x86-64.S
rename to arch/x86/parasite-head.S
diff --git a/include/processor-flags.h b/arch/x86/processor-flags.h
similarity index 100%
rename from include/processor-flags.h
rename to arch/x86/processor-flags.h
diff --git a/arch/x86/restorer_private.h b/arch/x86/restorer_private.h
new file mode 100644
index 0000000..09d452e
--- /dev/null
+++ b/arch/x86/restorer_private.h
@@ -0,0 +1,179 @@
+#ifndef X86_64_RESTORER_PRIVATE_
+#define X86_64_RESTORER_PRIVATE_
+
+struct pt_regs {
+	unsigned long	r15;
+	unsigned long	r14;
+	unsigned long	r13;
+	unsigned long	r12;
+	unsigned long	bp;
+	unsigned long	bx;
+
+	unsigned long	r11;
+	unsigned long	r10;
+	unsigned long	r9;
+	unsigned long	r8;
+	unsigned long	ax;
+	unsigned long	cx;
+	unsigned long	dx;
+	unsigned long	si;
+	unsigned long	di;
+	unsigned long	orig_ax;
+
+	unsigned long	ip;
+	unsigned long	cs;
+	unsigned long	flags;
+	unsigned long	sp;
+	unsigned long	ss;
+};
+
+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			__pad0;
+	unsigned long			err;
+	unsigned long			trapno;
+	unsigned long			oldmask;
+	unsigned long			cr2;
+	struct user_fpregs_entry	*fpstate;
+	unsigned long			reserved1[8];
+};
+
+#include <sigframe.h>
+
+struct rt_sigframe {
+	char			*pretcode;
+	struct rt_ucontext	uc;
+	struct rt_siginfo	info;
+
+	/* fp state follows here */
+};
+
+#define RT_SIGFRAME_UC(rt_sigframe) rt_sigframe->uc
+
+#define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid,      \
+			     thread_args, clone_restore_fn)             \
+	asm volatile(							\
+		     "clone_emul:				\n"	\
+		     "movq %2, %%rsi				\n"	\
+		     "subq $16, %%rsi			        \n"	\
+		     "movq %6, %%rdi				\n"	\
+		     "movq %%rdi, 8(%%rsi)			\n"	\
+		     "movq %5, %%rdi				\n"	\
+		     "movq %%rdi, 0(%%rsi)			\n"	\
+		     "movq %1, %%rdi				\n"	\
+		     "movq %3, %%rdx				\n"	\
+		     "movq %4, %%r10				\n"	\
+		     "movl $"__stringify(__NR_clone)", %%eax	\n"	\
+		     "syscall				        \n"	\
+									\
+		     "testq %%rax,%%rax			        \n"	\
+		     "jz thread_run				\n"	\
+									\
+		     "movq %%rax, %0				\n"	\
+		     "jmp clone_end				\n"	\
+									\
+		     "thread_run:				\n"	\
+		     "xorq %%rbp, %%rbp			        \n"	\
+		     "popq %%rax				\n"	\
+		     "popq %%rdi				\n"	\
+		     "callq *%%rax				\n"	\
+									\
+		     "clone_end:				\n"	\
+		     : "=r"(ret)					\
+		     : "g"(clone_flags),				\
+		       "g"(new_sp),					\
+		       "g"(&parent_tid),				\
+		       "g"(&thread_args[i].pid),			\
+		       "g"(clone_restore_fn),				\
+		       "g"(&thread_args[i])				\
+		     : "rax", "rdi", "rsi", "rdx", "r10", "memory")
+
+
+#define ARCH_RT_SIGRETURN(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_FAIL_CORE_RESTORE					\
+	asm volatile(						\
+		     "movq %0, %%rsp			    \n"	\
+		     "movq 0, %%rax			    \n"	\
+		     "jmp *%%rax			    \n"	\
+		     :						\
+		     : "r"(ret)					\
+		     : "memory")
+
+
+static int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
+{
+	long ret;
+	unsigned long fsgs_base;
+
+#define CPREG1(d)	f->uc.uc_mcontext.d = r->d
+#define CPREG2(d, s)	f->uc.uc_mcontext.d = r->s
+
+	CPREG1(r8);
+	CPREG1(r9);
+	CPREG1(r10);
+	CPREG1(r11);
+	CPREG1(r12);
+	CPREG1(r13);
+	CPREG1(r14);
+	CPREG1(r15);
+	CPREG2(rdi, di);
+	CPREG2(rsi, si);
+	CPREG2(rbp, bp);
+	CPREG2(rbx, bx);
+	CPREG2(rdx, dx);
+	CPREG2(rax, ax);
+	CPREG2(rcx, cx);
+	CPREG2(rsp, sp);
+	CPREG2(rip, ip);
+	CPREG2(eflags, flags);
+	CPREG1(cs);
+	CPREG1(gs);
+	CPREG1(fs);
+
+	fsgs_base = r->fs_base;
+	ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base);
+	if (ret) {
+		pr_info("SET_FS fail %ld\n", ret);
+		return -1;
+	}
+
+	fsgs_base = r->gs_base;
+	ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base);
+	if (ret) {
+		pr_info("SET_GS fail %ld\n", ret);
+		return -1;
+	}
+
+	return 0;
+}
+
+#endif
diff --git a/include/syscall-x86-64.def b/arch/x86/syscall-x86-64.def
similarity index 100%
rename from include/syscall-x86-64.def
rename to arch/x86/syscall-x86-64.def
diff --git a/include/bitops.h b/include/bitops.h
index 092f674..d7fcd62 100644
--- a/include/bitops.h
+++ b/include/bitops.h
@@ -1,8 +1,6 @@
 #ifndef CR_BITOPS_H_
 #define CR_BITOPS_H_
 
-#ifdef CONFIG_X86_64
-
 #define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
 #define BITS_PER_LONG		(8 * sizeof(long))
 #define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_LONG)
@@ -20,46 +18,7 @@
 
 #define ADDR				BITOP_ADDR(addr)
 
-static inline void set_bit(int nr, volatile unsigned long *addr)
-{
-	asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
-}
-
-static inline void change_bit(int nr, volatile unsigned long *addr)
-{
-	asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
-}
-
-static inline int test_bit(int nr, volatile const unsigned long *addr)
-{
-	int oldbit;
-
-	asm volatile("bt %2,%1\n\t"
-		     "sbb %0,%0"
-		     : "=r" (oldbit)
-		     : "m" (*(unsigned long *)addr), "Ir" (nr));
-
-	return oldbit;
-}
-
-static inline void clear_bit(int nr, volatile unsigned long *addr)
-{
-	asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
-}
-
-/**
- * __ffs - find first set bit in word
- * @word: The word to search
- *
- * Undefined if no bit exists, so code should check against 0 first.
- */
-static inline unsigned long __ffs(unsigned long word)
-{
-	asm("bsf %1,%0"
-		: "=r" (word)
-		: "rm" (word));
-	return word;
-}
+#include <arch_bitops.h>
 
 #define BITOP_WORD(nr)		((nr) / BITS_PER_LONG)
 
@@ -111,8 +70,4 @@ found_middle:
 	     i < sizeof(bitmask);				\
 	     i = find_next_bit(bitmask, sizeof(bitmask), i + 1))
 
-#else /* CONFIG_X86_64 */
-# error x86-32 is not implemented yet
-#endif /* CONFIG_X86_64 */
-
 #endif /* CR_BITOPS_H_ */
diff --git a/include/image.h b/include/image.h
index 916b9a8..39f68e6 100644
--- a/include/image.h
+++ b/include/image.h
@@ -105,25 +105,19 @@ struct page_entry {
 
 #define CR_CAP_SIZE	2
 
-#ifdef CONFIG_X86_64
-
 #define GDT_ENTRY_TLS_ENTRIES 3
-#define TASK_COMM_LEN 16
 
 #define TASK_PF_USED_MATH		0x00002000
 
-#ifdef CONFIG_X86_64
-# define AT_VECTOR_SIZE 44
-#else
-# define AT_VECTOR_SIZE 22		/* Not needed at moment */
-#endif
+
+  //#endif /* CONFIG_X86_64 */
 
 #define TASK_ALIVE		0x1
 #define TASK_DEAD		0x2
 #define TASK_STOPPED		0x3 /* FIXME - implement */
 #define TASK_HELPER		0x4
 
-#endif /* CONFIG_X86_64 */
+#define TASK_COMM_LEN 16
 
 /*
  * There are always 4 magic bytes at the
diff --git a/include/syscall-types.h b/include/syscall-types.h
index 261e288..5f90f2d 100644
--- a/include/syscall-types.h
+++ b/include/syscall-types.h
@@ -14,10 +14,6 @@
 
 #include "types.h"
 
-#ifndef CONFIG_X86_64
-# error x86-32 bit mode not yet implemented
-#endif
-
 struct cap_header {
 	u32 version;
 	int pid;
diff --git a/include/types.h b/include/types.h
index 9b7884f..40a5f78 100644
--- a/include/types.h
+++ b/include/types.h
@@ -84,10 +84,10 @@ typedef signed char		s8;
 #define _LINUX_CAPABILITY_VERSION_3	0x20080522
 #define _LINUX_CAPABILITY_U32S_3	2
 
-#ifdef CONFIG_X86_64
+#include <arch-types.h>
 
 typedef struct {
-	unsigned long sig[1];
+	u64 sig[1];
 } rt_sigset_t;
 
 typedef void rt_signalfn_t(int, siginfo_t *, void *);
@@ -104,8 +104,6 @@ typedef struct {
 } rt_sigaction_t;
 
 #define _KNSIG           64
-# define _NSIG_BPW      64
-
 #define _KNSIG_WORDS     (_KNSIG / _NSIG_BPW)
 
 typedef struct {
@@ -119,68 +117,6 @@ static inline void ksigfillset(k_rtsigset_t *set)
 		set->sig[i] = (unsigned long)-1;
 }
 
-typedef struct {
-	unsigned int	entry_number;
-	unsigned int	base_addr;
-	unsigned int	limit;
-	unsigned int	seg_32bit:1;
-	unsigned int	contents:2;
-	unsigned int	read_exec_only:1;
-	unsigned int	limit_in_pages:1;
-	unsigned int	seg_not_present:1;
-	unsigned int	useable:1;
-	unsigned int	lm:1;
-} user_desc_t;
-
-typedef struct {
-	unsigned long	r15;
-	unsigned long	r14;
-	unsigned long	r13;
-	unsigned long	r12;
-	unsigned long	bp;
-	unsigned long	bx;
-	unsigned long	r11;
-	unsigned long	r10;
-	unsigned long	r9;
-	unsigned long	r8;
-	unsigned long	ax;
-	unsigned long	cx;
-	unsigned long	dx;
-	unsigned long	si;
-	unsigned long	di;
-	unsigned long	orig_ax;
-	unsigned long	ip;
-	unsigned long	cs;
-	unsigned long	flags;
-	unsigned long	sp;
-	unsigned long	ss;
-	unsigned long	fs_base;
-	unsigned long	gs_base;
-	unsigned long	ds;
-	unsigned long	es;
-	unsigned long	fs;
-	unsigned long	gs;
-} user_regs_struct_t;
-
-typedef struct {
-	unsigned short	cwd;
-	unsigned short	swd;
-	unsigned short	twd;	/* Note this is not the same as
-				   the 32bit/x87/FSAVE twd */
-	unsigned short	fop;
-	u64		rip;
-	u64		rdp;
-	u32		mxcsr;
-	u32		mxcsr_mask;
-	u32		st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
-	u32		xmm_space[64];	/* 16*16 bytes for each XMM-reg = 256 bytes */
-	u32		padding[24];
-} user_fpregs_struct_t;
-
-#else /* CONFIG_X86_64 */
-# error x86-32 bit mode not yet implemented
-#endif /* CONFIG_X86_64 */
-
 #define ASSIGN_TYPED(a, b) do { a = (typeof(a))b; } while (0)
 #define ASSIGN_MEMBER(a,b,m) do { ASSIGN_TYPED((a)->m, (b)->m); } while (0)
 
-- 
1.7.9.5



More information about the CRIU mailing list