Commit aff6918b authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

kernel: Fixups on segment loading in Elf handling

Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
parent b1739c08
......@@ -9,13 +9,18 @@ Elf file format, which includes
PT_CKPT_CORE -- 'core_entry' structure and PT_CKPT_PAGES --
a set of all pages which are to be read into process memory.
v2: (from Andrew Vagin)
- load fs_base and gs_base via do_arch_prctl
- don't load tls and segments, it will be done in __switch_to
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Andrew Vagin <avagin@openvz.org>
---
arch/x86/include/asm/elf.h | 3
arch/x86/vdso/vma.c | 22 ++
fs/binfmt_elf.c | 405 ++++++++++++++++++++++++++++++++++++++++++++-
fs/binfmt_elf.c | 402 ++++++++++++++++++++++++++++++++++++++++++++-
include/linux/elf_ckpt.h | 135 +++++++++++++++
4 files changed, 563 insertions(+), 2 deletions(-)
4 files changed, 560 insertions(+), 2 deletions(-)
Index: linux-2.6.git/arch/x86/include/asm/elf.h
===================================================================
......@@ -68,19 +73,22 @@ Index: linux-2.6.git/fs/binfmt_elf.c
===================================================================
--- linux-2.6.git.orig/fs/binfmt_elf.c
+++ linux-2.6.git/fs/binfmt_elf.c
@@ -36,6 +36,11 @@
@@ -35,6 +35,14 @@
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/page.h>
+#include <asm/prctl.h>
+#include <asm/proto.h>
+
+
+#include <linux/elf_ckpt.h>
+#include <linux/flex_array.h>
+#include <asm/tlbflush.h>
+#include <asm/desc.h>
+
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
static int load_elf_library(struct file *);
static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
@@ -556,6 +561,396 @@ static unsigned long randomize_stack_top
@@ -556,6 +564,390 @@ static unsigned long randomize_stack_top
#endif
}
......@@ -109,7 +117,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
+ int i, ret = -ENOEXEC;
+ loff_t off;
+
+ int cpu, seg;
+ int cpu;
+
+ BUILD_BUG_ON(CKPT_GDT_ENTRY_TLS_ENTRIES != GDT_ENTRY_TLS_ENTRIES);
+ BUILD_BUG_ON(CKPT_PAGE_SIZE != PAGE_SIZE);
......@@ -430,23 +438,17 @@ Index: linux-2.6.git/fs/binfmt_elf.c
+ thread->tls_array[i].b = core_entry.tls_array[i].b;
+ }
+
+ load_TLS(thread, cpu);
+
+ seg = thread->fsindex;
+ loadsegment(fs, seg);
+ savesegment(fs, seg);
+
+ if (seg != thread->fsindex) {
+ pr_err("Fixup on FS loading exception: %i %i\n",
+ thread->fsindex, seg);
+ if (core_entry.gpregs.fs_base) {
+ ret = do_arch_prctl(current, ARCH_SET_FS, core_entry.gpregs.fs_base);
+ if (ret)
+ goto out_unmap;
+ }
+
+ if (core_entry.gpregs.fs_base)
+ wrmsrl(MSR_FS_BASE, core_entry.gpregs.fs_base);
+
+ load_gs_index(thread->gsindex);
+ if (core_entry.gpregs.gs_base)
+ wrmsrl(MSR_GS_BASE, core_entry.gpregs.gs_base);
+ if (core_entry.gpregs.gs_base) {
+ ret = do_arch_prctl(current, ARCH_SET_GS, core_entry.gpregs.gs_base);
+ if (ret)
+ goto out_unmap;
+ }
+
+ put_cpu();
+
......@@ -477,7 +479,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
{
struct file *interpreter = NULL; /* to shut gcc up */
@@ -592,7 +987,9 @@ static int load_elf_binary(struct linux_
@@ -592,7 +984,9 @@ static int load_elf_binary(struct linux_
if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
goto out;
......@@ -488,7 +490,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
goto out;
if (!elf_check_arch(&loc->elf_ex))
goto out;
@@ -619,6 +1016,12 @@ static int load_elf_binary(struct linux_
@@ -619,6 +1013,12 @@ static int load_elf_binary(struct linux_
goto out_free_ph;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment