# 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
|