[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Move the gate page (vsyscall) out of the fixmap area into user address space,



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 822a27d28afeab1ffdf8ca8e8e8a11de5e7c7aec
# Parent  875e0e96e574cc8216394b7eb6eaa22474d0f216
Move the gate page (vsyscall) out of the fixmap area into user address space,
just below PAGE_OFFSET.

From: Gerd Hoffmann <kraxel@xxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r 875e0e96e574 -r 822a27d28afe 
linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c       Thu Feb 23 
15:22:17 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c       Thu Feb 23 
15:22:19 2006
@@ -13,6 +13,7 @@
 #include <asm/fixmap.h>
 #include <asm/processor.h>
 #include <asm/thread_info.h>
+#include <asm/elf.h>
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -70,5 +71,5 @@
 #endif
 
        DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
-       DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
+       DEFINE(VSYSCALL_BASE, VSYSCALL_BASE);
 }
diff -r 875e0e96e574 -r 822a27d28afe 
linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c  Thu Feb 23 15:22:17 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c  Thu Feb 23 15:22:19 2006
@@ -13,6 +13,7 @@
 #include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/elf.h>
+#include <linux/mm.h>
 
 #include <asm/cpufeature.h>
 #include <asm/msr.h>
@@ -47,25 +48,90 @@
  */
 extern const char vsyscall_int80_start, vsyscall_int80_end;
 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
+static void *syscall_page;
 
 int __init sysenter_setup(void)
 {
-       void *page = (void *)get_zeroed_page(GFP_ATOMIC);
-
-       __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
+       syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
 
 #ifdef CONFIG_X86_SYSENTER
        if (boot_cpu_has(X86_FEATURE_SEP)) {
-               memcpy(page,
+               memcpy(syscall_page,
                       &vsyscall_sysenter_start,
                       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
                return 0;
        }
 #endif
 
-       memcpy(page,
+       memcpy(syscall_page,
               &vsyscall_int80_start,
               &vsyscall_int80_end - &vsyscall_int80_start);
 
        return 0;
 }
+
+static struct page*
+syscall_nopage(struct vm_area_struct *vma, unsigned long adr, int *type)
+{
+       struct page *p = virt_to_page(adr - vma->vm_start + syscall_page);
+       get_page(p);
+       return p;
+}
+
+/* Prevent VMA merging */
+static void syscall_vma_close(struct vm_area_struct *vma)
+{
+}
+
+static struct vm_operations_struct syscall_vm_ops = {
+       .close = syscall_vma_close,
+       .nopage = syscall_nopage,
+};
+
+/* Setup a VMA at program startup for the vsyscall page */
+int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
+{
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = current->mm;
+       int ret;
+
+       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+       if (!vma)
+               return -ENOMEM;
+
+       memset(vma, 0, sizeof(struct vm_area_struct));
+       /* Could randomize here */
+       vma->vm_start = VSYSCALL_BASE;
+       vma->vm_end = VSYSCALL_BASE + PAGE_SIZE;
+       /* MAYWRITE to allow gdb to COW and set breakpoints */
+       vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
+       vma->vm_flags |= mm->def_flags;
+       vma->vm_page_prot = protection_map[vma->vm_flags & 7];
+       vma->vm_ops = &syscall_vm_ops;
+       vma->vm_mm = mm;
+
+       down_write(&mm->mmap_sem);
+       if ((ret = insert_vm_struct(mm, vma))) {
+               up_write(&mm->mmap_sem);
+               kmem_cache_free(vm_area_cachep, vma);
+               return ret;
+       }
+       mm->total_vm++;
+       up_write(&mm->mmap_sem);
+       return 0;
+}
+
+struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
+{
+       return NULL;
+}
+
+int in_gate_area(struct task_struct *task, unsigned long addr)
+{
+       return 0;
+}
+
+int in_gate_area_no_task(unsigned long addr)
+{
+       return 0;
+}
diff -r 875e0e96e574 -r 822a27d28afe 
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Thu Feb 23 15:22:17 2006
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Thu Feb 23 15:22:19 2006
@@ -194,7 +194,6 @@
        }
        switch (idx) {
        case FIX_WP_TEST:
-       case FIX_VSYSCALL:
 #ifdef CONFIG_X86_F00F_BUG
        case FIX_F00F_IDT:
 #endif
diff -r 875e0e96e574 -r 822a27d28afe 
linux-2.6-xen-sparse/include/asm-i386/a.out.h
--- a/linux-2.6-xen-sparse/include/asm-i386/a.out.h     Thu Feb 23 15:22:17 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/a.out.h     Thu Feb 23 15:22:19 2006
@@ -19,7 +19,7 @@
 
 #ifdef __KERNEL__
 
-#define STACK_TOP      TASK_SIZE
+#define STACK_TOP      (TASK_SIZE - 3*PAGE_SIZE)
 
 #endif
 
diff -r 875e0e96e574 -r 822a27d28afe linux-2.6-xen-sparse/include/asm-i386/elf.h
--- a/linux-2.6-xen-sparse/include/asm-i386/elf.h       Thu Feb 23 15:22:17 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/elf.h       Thu Feb 23 15:22:19 2006
@@ -129,10 +129,15 @@
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, 
elf_xfpregs)
 
-#define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
+#define VSYSCALL_BASE  (PAGE_OFFSET - 2*PAGE_SIZE)
 #define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
 #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
 extern void __kernel_vsyscall;
+
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+                                       int executable_stack);
 
 #define ARCH_DLINFO                                            \
 do {                                                           \
diff -r 875e0e96e574 -r 822a27d28afe 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h       Thu Feb 
23 15:22:17 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h       Thu Feb 
23 15:22:19 2006
@@ -53,7 +53,6 @@
  */
 enum fixed_addresses {
        FIX_HOLE,
-       FIX_VSYSCALL,
 #ifdef CONFIG_X86_LOCAL_APIC
        FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
 #endif
@@ -123,14 +122,6 @@
 #define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
 #define __virt_to_fix(x)       ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
 
-/*
- * This is the range that is readable by user mode, and things
- * acting like user mode such as get_user_pages.
- */
-#define FIXADDR_USER_START     (__fix_to_virt(FIX_VSYSCALL))
-#define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
-
-
 extern void __this_fixmap_does_not_exist(void);
 
 /*
diff -r 875e0e96e574 -r 822a27d28afe 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Thu Feb 23 
15:22:17 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Thu Feb 23 
15:22:19 2006
@@ -317,6 +317,8 @@
 #define virt_to_mfn(v)         (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
 #define mfn_to_virt(m)         (__va(mfn_to_pfn(m) << PAGE_SHIFT))
 
+#define __HAVE_ARCH_GATE_AREA 1
+
 #endif /* __KERNEL__ */
 
 #include <asm-generic/page.h>

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.