[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, ®s)) {
+ 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, ®s);
+
+ ret = __parasite_execute(ctl, ctl->pid, ®s);
+ 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, ®s);
+
+ ret = __parasite_execute(ctl, ctl->pid, ®s);
+ 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