- x86-move-vsyscall-page-out-of-fixmap-above-stack.patch removed from -mm tree

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

 



The patch titled

     x86: move vsyscall page out of fixmap, above stack

has been removed from the -mm tree.  Its filename is

     x86-move-vsyscall-page-out-of-fixmap-above-stack.patch

This patch was probably dropped from -mm because
it has now been merged into a subsystem tree or
into Linus's tree, or because it was folded into
its parent patch in the -mm tree.

------------------------------------------------------
Subject: x86: move vsyscall page out of fixmap, above stack
From: Rusty Russell <rusty@xxxxxxxxxxxxxxx>


Author: Gerd Hoffmann <kraxel@xxxxxxx>

Hypervisors want to use memory at the top of the address space (eg.  64MB
for Xen, or 168MB for Xen w/ PAE).  Creating this hole means moving the
vsyscall page away from 0xffffe000.

If we create this hole statically with a config option, we give up, say,
256MB of lowmem for the case where a hypervisor-capable kernel is actually
running on native hardware.

If we create this hole dynamically and leave the vsyscall page at the top
of kernel memory, we would have to patch up the vsyscall elf header at boot
time to reflect where we put it.

Instead, this patch moves the vsyscall page into the user address region,
just below PAGE_OFFSET: it's still at a fixed address, but it's not where
the hypervisor wants to be, so resizing the hole is trivial.

Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 arch/i386/kernel/asm-offsets.c |    3 -
 arch/i386/kernel/sysenter.c    |   76 ++++++++++++++++++++++++++++---
 arch/i386/mm/pgtable.c         |   12 ++++
 include/asm-i386/a.out.h       |    2 
 include/asm-i386/elf.h         |    7 ++
 include/asm-i386/fixmap.h      |   13 +----
 include/asm-i386/page.h        |    4 +
 7 files changed, 98 insertions(+), 19 deletions(-)

diff -puN arch/i386/kernel/asm-offsets.c~x86-move-vsyscall-page-out-of-fixmap-above-stack arch/i386/kernel/asm-offsets.c
--- devel/arch/i386/kernel/asm-offsets.c~x86-move-vsyscall-page-out-of-fixmap-above-stack	2006-05-21 02:41:49.000000000 -0700
+++ devel-akpm/arch/i386/kernel/asm-offsets.c	2006-05-21 02:42:18.000000000 -0700
@@ -14,6 +14,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))
@@ -69,7 +70,7 @@ void foo(void)
 		 sizeof(struct tss_struct));
 
 	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
-	DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
+	DEFINE(VSYSCALL_BASE, VSYSCALL_BASE);
 
 	OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
 }
diff -puN arch/i386/kernel/sysenter.c~x86-move-vsyscall-page-out-of-fixmap-above-stack arch/i386/kernel/sysenter.c
--- devel/arch/i386/kernel/sysenter.c~x86-move-vsyscall-page-out-of-fixmap-above-stack	2006-05-21 02:41:49.000000000 -0700
+++ devel-akpm/arch/i386/kernel/sysenter.c	2006-05-21 02:51:48.000000000 -0700
@@ -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>
@@ -45,23 +46,88 @@ void enable_sep_cpu(void)
  */
 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);
 
 	if (!boot_cpu_has(X86_FEATURE_SEP)) {
-		memcpy(page,
+		memcpy(syscall_page,
 		       &vsyscall_int80_start,
 		       &vsyscall_int80_end - &vsyscall_int80_start);
 		return 0;
 	}
 
-	memcpy(page,
+	memcpy(syscall_page,
 	       &vsyscall_sysenter_start,
 	       &vsyscall_sysenter_end - &vsyscall_sysenter_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 -puN arch/i386/mm/pgtable.c~x86-move-vsyscall-page-out-of-fixmap-above-stack arch/i386/mm/pgtable.c
--- devel/arch/i386/mm/pgtable.c~x86-move-vsyscall-page-out-of-fixmap-above-stack	2006-05-21 02:41:49.000000000 -0700
+++ devel-akpm/arch/i386/mm/pgtable.c	2006-05-21 02:51:48.000000000 -0700
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -138,6 +139,10 @@ void set_pmd_pfn(unsigned long vaddr, un
 	__flush_tlb_one(vaddr);
 }
 
+static int nr_fixmaps = 0;
+unsigned long __FIXADDR_TOP = 0xfffff000;
+EXPORT_SYMBOL(__FIXADDR_TOP);
+
 void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
 {
 	unsigned long address = __fix_to_virt(idx);
@@ -147,6 +152,13 @@ void __set_fixmap (enum fixed_addresses 
 		return;
 	}
 	set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
+	nr_fixmaps++;
+}
+
+void set_fixaddr_top(unsigned long top)
+{
+	BUG_ON(nr_fixmaps > 0);
+	__FIXADDR_TOP = top - PAGE_SIZE;
 }
 
 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
diff -puN include/asm-i386/a.out.h~x86-move-vsyscall-page-out-of-fixmap-above-stack include/asm-i386/a.out.h
--- devel/include/asm-i386/a.out.h~x86-move-vsyscall-page-out-of-fixmap-above-stack	2006-05-21 02:41:49.000000000 -0700
+++ devel-akpm/include/asm-i386/a.out.h	2006-05-21 02:41:49.000000000 -0700
@@ -19,7 +19,7 @@ struct exec
 
 #ifdef __KERNEL__
 
-#define STACK_TOP	TASK_SIZE
+#define STACK_TOP	(TASK_SIZE - 3*PAGE_SIZE)
 
 #endif
 
diff -puN include/asm-i386/elf.h~x86-move-vsyscall-page-out-of-fixmap-above-stack include/asm-i386/elf.h
--- devel/include/asm-i386/elf.h~x86-move-vsyscall-page-out-of-fixmap-above-stack	2006-05-21 02:41:49.000000000 -0700
+++ devel-akpm/include/asm-i386/elf.h	2006-05-21 02:51:48.000000000 -0700
@@ -129,11 +129,16 @@ extern int dump_task_extended_fpu (struc
 #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 {								\
 		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);	\
diff -puN include/asm-i386/fixmap.h~x86-move-vsyscall-page-out-of-fixmap-above-stack include/asm-i386/fixmap.h
--- devel/include/asm-i386/fixmap.h~x86-move-vsyscall-page-out-of-fixmap-above-stack	2006-05-21 02:41:49.000000000 -0700
+++ devel-akpm/include/asm-i386/fixmap.h	2006-05-21 02:41:49.000000000 -0700
@@ -19,7 +19,7 @@
  * Leave one empty page between vmalloc'ed areas and
  * the start of the fixmap.
  */
-#define __FIXADDR_TOP	0xfffff000
+extern unsigned long __FIXADDR_TOP;
 
 #ifndef __ASSEMBLY__
 #include <linux/kernel.h>
@@ -51,7 +51,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
@@ -94,6 +93,8 @@ enum fixed_addresses {
 extern void __set_fixmap (enum fixed_addresses idx,
 					unsigned long phys, pgprot_t flags);
 
+extern void set_fixaddr_top(unsigned long top);
+
 #define set_fixmap(idx, phys) \
 		__set_fixmap(idx, phys, PAGE_KERNEL)
 /*
@@ -115,14 +116,6 @@ extern void __set_fixmap (enum fixed_add
 #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 -puN include/asm-i386/page.h~x86-move-vsyscall-page-out-of-fixmap-above-stack include/asm-i386/page.h
--- devel/include/asm-i386/page.h~x86-move-vsyscall-page-out-of-fixmap-above-stack	2006-05-21 02:41:49.000000000 -0700
+++ devel-akpm/include/asm-i386/page.h	2006-05-21 02:41:49.000000000 -0700
@@ -120,7 +120,7 @@ extern int page_is_ram(unsigned long pag
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+#define MAXMEM			(__FIXADDR_TOP-__PAGE_OFFSET-__VMALLOC_RESERVE)
 #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
@@ -139,6 +139,8 @@ extern int page_is_ram(unsigned long pag
 #include <asm-generic/memory_model.h>
 #include <asm-generic/page.h>
 
+#define __HAVE_ARCH_GATE_AREA 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _I386_PAGE_H */
_

Patches currently in -mm which might be from rusty@xxxxxxxxxxxxxxx are

origin.patch
x86-increase-interrupt-vector-range.patch
vdso-randomize-the-i386-vdso-by-moving-it-into-a-vma.patch
vdso-randomize-the-i386-vdso-by-moving-it-into-a-vma-tidy.patch
x86-move-vsyscall-page-out-of-fixmap-above-stack.patch
kernel-kernel-cpuc-to-mutexes.patch
ensure-null-deref-cant-possibly-happen-in-is_exported.patch
define-__raw_get_cpu_var-and-use-it.patch
allow-for-per-cpu-data-being-in-tdata-and-tbss-sections.patch
allow-for-per-cpu-data-being-in-tdata-and-tbss-sections-fix.patch
allow-for-per-cpu-data-being-in-tdata-and-tbss-sections-tidy.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux