ia64/xen-unstable

changeset 8983:822a27d28afe

Move the gate page (vsyscall) out of the fixmap area into user address space,
just below PAGE_OFFSET.

From: Gerd Hoffmann <kraxel@suse.de>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Thu Feb 23 15:22:19 2006 +0000 (2006-02-23)
parents 875e0e96e574
children d161c07014a3
files linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c linux-2.6-xen-sparse/include/asm-i386/a.out.h linux-2.6-xen-sparse/include/asm-i386/elf.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c	Thu Feb 23 15:22:17 2006 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/asm-offsets.c	Thu Feb 23 15:22:19 2006 +0000
     1.3 @@ -13,6 +13,7 @@
     1.4  #include <asm/fixmap.h>
     1.5  #include <asm/processor.h>
     1.6  #include <asm/thread_info.h>
     1.7 +#include <asm/elf.h>
     1.8  
     1.9  #define DEFINE(sym, val) \
    1.10          asm volatile("\n->" #sym " %0 " #val : : "i" (val))
    1.11 @@ -70,5 +71,5 @@ void foo(void)
    1.12  #endif
    1.13  
    1.14  	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
    1.15 -	DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
    1.16 +	DEFINE(VSYSCALL_BASE, VSYSCALL_BASE);
    1.17  }
     2.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c	Thu Feb 23 15:22:17 2006 +0000
     2.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c	Thu Feb 23 15:22:19 2006 +0000
     2.3 @@ -13,6 +13,7 @@
     2.4  #include <linux/gfp.h>
     2.5  #include <linux/string.h>
     2.6  #include <linux/elf.h>
     2.7 +#include <linux/mm.h>
     2.8  
     2.9  #include <asm/cpufeature.h>
    2.10  #include <asm/msr.h>
    2.11 @@ -47,25 +48,90 @@ void enable_sep_cpu(void)
    2.12   */
    2.13  extern const char vsyscall_int80_start, vsyscall_int80_end;
    2.14  extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
    2.15 +static void *syscall_page;
    2.16  
    2.17  int __init sysenter_setup(void)
    2.18  {
    2.19 -	void *page = (void *)get_zeroed_page(GFP_ATOMIC);
    2.20 -
    2.21 -	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
    2.22 +	syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
    2.23  
    2.24  #ifdef CONFIG_X86_SYSENTER
    2.25  	if (boot_cpu_has(X86_FEATURE_SEP)) {
    2.26 -		memcpy(page,
    2.27 +		memcpy(syscall_page,
    2.28  		       &vsyscall_sysenter_start,
    2.29  		       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
    2.30  		return 0;
    2.31  	}
    2.32  #endif
    2.33  
    2.34 -	memcpy(page,
    2.35 +	memcpy(syscall_page,
    2.36  	       &vsyscall_int80_start,
    2.37  	       &vsyscall_int80_end - &vsyscall_int80_start);
    2.38  
    2.39  	return 0;
    2.40  }
    2.41 +
    2.42 +static struct page*
    2.43 +syscall_nopage(struct vm_area_struct *vma, unsigned long adr, int *type)
    2.44 +{
    2.45 +	struct page *p = virt_to_page(adr - vma->vm_start + syscall_page);
    2.46 +	get_page(p);
    2.47 +	return p;
    2.48 +}
    2.49 +
    2.50 +/* Prevent VMA merging */
    2.51 +static void syscall_vma_close(struct vm_area_struct *vma)
    2.52 +{
    2.53 +}
    2.54 +
    2.55 +static struct vm_operations_struct syscall_vm_ops = {
    2.56 +	.close = syscall_vma_close,
    2.57 +	.nopage = syscall_nopage,
    2.58 +};
    2.59 +
    2.60 +/* Setup a VMA at program startup for the vsyscall page */
    2.61 +int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
    2.62 +{
    2.63 +	struct vm_area_struct *vma;
    2.64 +	struct mm_struct *mm = current->mm;
    2.65 +	int ret;
    2.66 +
    2.67 +	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
    2.68 +	if (!vma)
    2.69 +		return -ENOMEM;
    2.70 +
    2.71 +	memset(vma, 0, sizeof(struct vm_area_struct));
    2.72 +	/* Could randomize here */
    2.73 +	vma->vm_start = VSYSCALL_BASE;
    2.74 +	vma->vm_end = VSYSCALL_BASE + PAGE_SIZE;
    2.75 +	/* MAYWRITE to allow gdb to COW and set breakpoints */
    2.76 +	vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
    2.77 +	vma->vm_flags |= mm->def_flags;
    2.78 +	vma->vm_page_prot = protection_map[vma->vm_flags & 7];
    2.79 +	vma->vm_ops = &syscall_vm_ops;
    2.80 +	vma->vm_mm = mm;
    2.81 +
    2.82 +	down_write(&mm->mmap_sem);
    2.83 +	if ((ret = insert_vm_struct(mm, vma))) {
    2.84 +		up_write(&mm->mmap_sem);
    2.85 +		kmem_cache_free(vm_area_cachep, vma);
    2.86 +		return ret;
    2.87 +	}
    2.88 +	mm->total_vm++;
    2.89 +	up_write(&mm->mmap_sem);
    2.90 +	return 0;
    2.91 +}
    2.92 +
    2.93 +struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
    2.94 +{
    2.95 +	return NULL;
    2.96 +}
    2.97 +
    2.98 +int in_gate_area(struct task_struct *task, unsigned long addr)
    2.99 +{
   2.100 +	return 0;
   2.101 +}
   2.102 +
   2.103 +int in_gate_area_no_task(unsigned long addr)
   2.104 +{
   2.105 +	return 0;
   2.106 +}
     3.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Thu Feb 23 15:22:17 2006 +0000
     3.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Thu Feb 23 15:22:19 2006 +0000
     3.3 @@ -194,7 +194,6 @@ void __set_fixmap (enum fixed_addresses 
     3.4  	}
     3.5  	switch (idx) {
     3.6  	case FIX_WP_TEST:
     3.7 -	case FIX_VSYSCALL:
     3.8  #ifdef CONFIG_X86_F00F_BUG
     3.9  	case FIX_F00F_IDT:
    3.10  #endif
     4.1 --- a/linux-2.6-xen-sparse/include/asm-i386/a.out.h	Thu Feb 23 15:22:17 2006 +0000
     4.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/a.out.h	Thu Feb 23 15:22:19 2006 +0000
     4.3 @@ -19,7 +19,7 @@ struct exec
     4.4  
     4.5  #ifdef __KERNEL__
     4.6  
     4.7 -#define STACK_TOP	TASK_SIZE
     4.8 +#define STACK_TOP	(TASK_SIZE - 3*PAGE_SIZE)
     4.9  
    4.10  #endif
    4.11  
     5.1 --- a/linux-2.6-xen-sparse/include/asm-i386/elf.h	Thu Feb 23 15:22:17 2006 +0000
     5.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/elf.h	Thu Feb 23 15:22:19 2006 +0000
     5.3 @@ -129,11 +129,16 @@ extern int dump_task_extended_fpu (struc
     5.4  #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
     5.5  #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
     5.6  
     5.7 -#define VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
     5.8 +#define VSYSCALL_BASE	(PAGE_OFFSET - 2*PAGE_SIZE)
     5.9  #define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
    5.10  #define VSYSCALL_ENTRY	((unsigned long) &__kernel_vsyscall)
    5.11  extern void __kernel_vsyscall;
    5.12  
    5.13 +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
    5.14 +struct linux_binprm;
    5.15 +extern int arch_setup_additional_pages(struct linux_binprm *bprm,
    5.16 +                                       int executable_stack);
    5.17 +
    5.18  #define ARCH_DLINFO						\
    5.19  do {								\
    5.20  		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);	\
     6.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h	Thu Feb 23 15:22:17 2006 +0000
     6.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h	Thu Feb 23 15:22:19 2006 +0000
     6.3 @@ -53,7 +53,6 @@
     6.4   */
     6.5  enum fixed_addresses {
     6.6  	FIX_HOLE,
     6.7 -	FIX_VSYSCALL,
     6.8  #ifdef CONFIG_X86_LOCAL_APIC
     6.9  	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
    6.10  #endif
    6.11 @@ -123,14 +122,6 @@ extern void __set_fixmap(
    6.12  #define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
    6.13  #define __virt_to_fix(x)	((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
    6.14  
    6.15 -/*
    6.16 - * This is the range that is readable by user mode, and things
    6.17 - * acting like user mode such as get_user_pages.
    6.18 - */
    6.19 -#define FIXADDR_USER_START	(__fix_to_virt(FIX_VSYSCALL))
    6.20 -#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
    6.21 -
    6.22 -
    6.23  extern void __this_fixmap_does_not_exist(void);
    6.24  
    6.25  /*
     7.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Thu Feb 23 15:22:17 2006 +0000
     7.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Thu Feb 23 15:22:19 2006 +0000
     7.3 @@ -317,6 +317,8 @@ extern int page_is_ram(unsigned long pag
     7.4  #define virt_to_mfn(v)		(pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
     7.5  #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
     7.6  
     7.7 +#define __HAVE_ARCH_GATE_AREA 1
     7.8 +
     7.9  #endif /* __KERNEL__ */
    7.10  
    7.11  #include <asm-generic/page.h>