diff --git a/kernel/binfmt-elf-for-cr-5 b/kernel/binfmt-elf-for-cr-5 index 2fc4b1580..41d167f89 100644 --- a/kernel/binfmt-elf-for-cr-5 +++ b/kernel/binfmt-elf-for-cr-5 @@ -27,7 +27,7 @@ Signed-off-by: Cyrill Gorcunov arch/x86/include/asm/elf.h | 3 arch/x86/include/asm/elf_ckpt.h | 80 ++++++++ arch/x86/kernel/Makefile | 2 - arch/x86/kernel/elf_ckpt.c | 109 +++++++++++ + arch/x86/kernel/elf_ckpt.c | 145 +++++++++++++++ arch/x86/vdso/vma.c | 22 ++ fs/Kconfig.binfmt | 11 + fs/Makefile | 1 @@ -36,7 +36,7 @@ Signed-off-by: Cyrill Gorcunov fs/exec.c | 27 +- include/linux/binfmts.h | 1 include/linux/elf_ckpt.h | 90 +++++++++ - 12 files changed, 732 insertions(+), 12 deletions(-) + 12 files changed, 768 insertions(+), 12 deletions(-) Index: linux-2.6.git/arch/x86/include/asm/elf.h =================================================================== @@ -154,7 +154,7 @@ Index: linux-2.6.git/arch/x86/kernel/elf_ckpt.c =================================================================== --- /dev/null +++ linux-2.6.git/arch/x86/kernel/elf_ckpt.c -@@ -0,0 +1,109 @@ +@@ -0,0 +1,145 @@ +#include +#include +#include @@ -194,30 +194,66 @@ Index: linux-2.6.git/arch/x86/kernel/elf_ckpt.c + +#ifdef CONFIG_X86_64 + ++#define cp_reg(s, d, r) s.r = d.r ++ +int load_elf_ckpt_arch(struct task_struct *tsk, struct pt_regs *regs, + struct core_entry *core_entry) +{ + struct ckpt_arch_entry *arch = (struct ckpt_arch_entry *)core_entry->arch; + struct thread_struct *thread = ¤t->thread; -+ struct pt_regs *pt_regs_me = task_pt_regs(current); ++ ++ struct user_regs_struct gpregs; ++ struct user_i387_struct fpregs; ++ + mm_segment_t old_fs; + int i, ret; + + BUILD_BUG_ON(CKPT_GDT_ENTRY_TLS_ENTRIES != GDT_ENTRY_TLS_ENTRIES); + BUILD_BUG_ON(sizeof(struct ckpt_arch_entry) > CKPT_ARCH_SIZE); + ++ memset(&gpregs, 0, sizeof(gpregs)); ++ memset(&fpregs, 0, sizeof(fpregs)); ++ + /* + * Registers setup. + */ + ++ cp_reg(arch->gpregs, gpregs, r15); ++ cp_reg(arch->gpregs, gpregs, r14); ++ cp_reg(arch->gpregs, gpregs, r13); ++ cp_reg(arch->gpregs, gpregs, r12); ++ cp_reg(arch->gpregs, gpregs, bp); ++ cp_reg(arch->gpregs, gpregs, bx); ++ cp_reg(arch->gpregs, gpregs, r11); ++ cp_reg(arch->gpregs, gpregs, r10); ++ cp_reg(arch->gpregs, gpregs, r9); ++ cp_reg(arch->gpregs, gpregs, r8); ++ cp_reg(arch->gpregs, gpregs, ax); ++ cp_reg(arch->gpregs, gpregs, cx); ++ cp_reg(arch->gpregs, gpregs, dx); ++ cp_reg(arch->gpregs, gpregs, si); ++ cp_reg(arch->gpregs, gpregs, di); ++ cp_reg(arch->gpregs, gpregs, orig_ax); ++ cp_reg(arch->gpregs, gpregs, ip); ++ cp_reg(arch->gpregs, gpregs, cs); ++ cp_reg(arch->gpregs, gpregs, flags); ++ cp_reg(arch->gpregs, gpregs, sp); ++ cp_reg(arch->gpregs, gpregs, ss); ++ cp_reg(arch->gpregs, gpregs, fs_base); ++ cp_reg(arch->gpregs, gpregs, gs_base); ++ cp_reg(arch->gpregs, gpregs, ds); ++ cp_reg(arch->gpregs, gpregs, es); ++ cp_reg(arch->gpregs, gpregs, fs); ++ cp_reg(arch->gpregs, gpregs, gs); ++ + old_fs = get_fs(); + set_fs(KERNEL_DS); -+ ret = arch_ptrace(current, PTRACE_SETREGS, 0, (unsigned long)&arch->gpregs); ++ ret = arch_ptrace(current, PTRACE_SETREGS, 0, (unsigned long)&gpregs); + set_fs(old_fs); + if (ret) + goto out; + -+ *regs = *pt_regs_me; ++ *regs = *task_pt_regs(current); + + thread->usersp = arch->gpregs.sp; + thread->ds = arch->gpregs.ds; @@ -233,23 +269,27 @@ Index: linux-2.6.git/arch/x86/kernel/elf_ckpt.c + thread->tls_array[i].b = arch->tls_array[i].b; + } + -+ if (arch->gpregs.fs_base) { -+ ret = do_arch_prctl(current, ARCH_SET_FS, arch->gpregs.fs_base); -+ if (ret) -+ goto out_put; -+ } -+ -+ if (arch->gpregs.gs_base) { -+ ret = do_arch_prctl(current, ARCH_SET_GS, arch->gpregs.gs_base); -+ if (ret) -+ goto out_put; -+ } -+ + /* Restoring FPU */ + if (core_entry->task_flags & PF_USED_MATH) { ++ ++ cp_reg(arch->fpregs, fpregs, cwd); ++ cp_reg(arch->fpregs, fpregs, swd); ++ cp_reg(arch->fpregs, fpregs, twd); ++ cp_reg(arch->fpregs, fpregs, fop); ++ cp_reg(arch->fpregs, fpregs, rip); ++ cp_reg(arch->fpregs, fpregs, rdp); ++ cp_reg(arch->fpregs, fpregs, mxcsr); ++ cp_reg(arch->fpregs, fpregs, mxcsr_mask); ++ ++ for (i = 0; i < ARRAY_SIZE(arch->fpregs.st_space); i++) ++ cp_reg(arch->fpregs, fpregs, st_space[i]); ++ ++ for (i = 0; i < ARRAY_SIZE(arch->fpregs.xmm_space); i++) ++ cp_reg(arch->fpregs, fpregs, xmm_space[i]); ++ + old_fs = get_fs(); + set_fs(KERNEL_DS); -+ ret = arch_ptrace(current, PTRACE_SETFPREGS, 0, (unsigned long)&arch->fpregs); ++ ret = arch_ptrace(current, PTRACE_SETFPREGS, 0, (unsigned long)&fpregs); + set_fs(old_fs); + if (ret) + goto out; @@ -257,10 +297,6 @@ Index: linux-2.6.git/arch/x86/kernel/elf_ckpt.c + +out: + return ret; -+ -+out_put: -+ put_cpu(); -+ goto out; +} + +#endif /* CONFIG_X86_64 */