aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarvey Harrison <harvey.harrison@gmail.com>2008-01-30 07:31:10 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:31:10 -0500
commit675a0813609f9097e323261b1cc4b9dc3f50d40b (patch)
treecb23f505f2e2d8a0f9b982ffa7c63858052cf036
parentf3f20de87c03a90add5e34806c28a03a0d60bde0 (diff)
x86: unify mmap_{32|64}.c
mmap_is_ia32 always true for X86_32, or while emulating IA32 on X86_64 Randomization not supported on X86_32 in legacy layout. Both layouts allow randomization on X86_64. Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/mm/Makefile_322
-rw-r--r--arch/x86/mm/Makefile_643
-rw-r--r--arch/x86/mm/mmap.c (renamed from arch/x86/mm/mmap_64.c)95
-rw-r--r--arch/x86/mm/mmap_32.c81
4 files changed, 53 insertions, 128 deletions
diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32
index 362b4ad082de..a01aca79dc69 100644
--- a/arch/x86/mm/Makefile_32
+++ b/arch/x86/mm/Makefile_32
@@ -2,7 +2,7 @@
2# Makefile for the linux i386-specific parts of the memory manager. 2# Makefile for the linux i386-specific parts of the memory manager.
3# 3#
4 4
5obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap_32.o 5obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap.o
6 6
7obj-$(CONFIG_NUMA) += discontig_32.o 7obj-$(CONFIG_NUMA) += discontig_32.o
8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64
index d18baed54fc6..b5a74486c3aa 100644
--- a/arch/x86/mm/Makefile_64
+++ b/arch/x86/mm/Makefile_64
@@ -2,9 +2,8 @@
2# Makefile for the linux x86_64-specific parts of the memory manager. 2# Makefile for the linux x86_64-specific parts of the memory manager.
3# 3#
4 4
5obj-y := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap_64.o 5obj-y := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap.o
6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
7obj-$(CONFIG_NUMA) += numa_64.o 7obj-$(CONFIG_NUMA) += numa_64.o
8obj-$(CONFIG_K8_NUMA) += k8topology_64.o 8obj-$(CONFIG_K8_NUMA) += k8topology_64.o
9obj-$(CONFIG_ACPI_NUMA) += srat_64.o 9obj-$(CONFIG_ACPI_NUMA) += srat_64.o
10obj-$(CONFIG_IA32_EMULATION) += mmap_32.o
diff --git a/arch/x86/mm/mmap_64.c b/arch/x86/mm/mmap.c
index 119bf34ec529..56fe7124fbec 100644
--- a/arch/x86/mm/mmap_64.c
+++ b/arch/x86/mm/mmap.c
@@ -1,7 +1,5 @@
1/* 1/*
2 * linux/arch/x86-64/mm/mmap.c 2 * Flexible mmap layout support
3 *
4 * flexible mmap layout support
5 * 3 *
6 * Based on code by Ingo Molnar and Andi Kleen, copyrighted 4 * Based on code by Ingo Molnar and Andi Kleen, copyrighted
7 * as follows: 5 * as follows:
@@ -24,7 +22,6 @@
24 * You should have received a copy of the GNU General Public License 22 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software 23 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */ 25 */
29 26
30#include <linux/personality.h> 27#include <linux/personality.h>
@@ -32,7 +29,6 @@
32#include <linux/random.h> 29#include <linux/random.h>
33#include <linux/limits.h> 30#include <linux/limits.h>
34#include <linux/sched.h> 31#include <linux/sched.h>
35#include <asm/ia32.h>
36 32
37/* 33/*
38 * Top of mmap area (just below the process stack). 34 * Top of mmap area (just below the process stack).
@@ -42,20 +38,14 @@
42#define MIN_GAP (128*1024*1024) 38#define MIN_GAP (128*1024*1024)
43#define MAX_GAP (TASK_SIZE/6*5) 39#define MAX_GAP (TASK_SIZE/6*5)
44 40
45static unsigned long mmap_base(void) 41/*
46{ 42 * True on X86_32 or when emulating IA32 on X86_64
47 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; 43 */
48 44static int mmap_is_ia32(void)
49 if (gap < MIN_GAP)
50 gap = MIN_GAP;
51 else if (gap > MAX_GAP)
52 gap = MAX_GAP;
53
54 return TASK_SIZE - (gap & PAGE_MASK);
55}
56
57static int mmap_is_32(void)
58{ 45{
46#ifdef CONFIG_X86_32
47 return 1;
48#endif
59#ifdef CONFIG_IA32_EMULATION 49#ifdef CONFIG_IA32_EMULATION
60 if (test_thread_flag(TIF_IA32)) 50 if (test_thread_flag(TIF_IA32))
61 return 1; 51 return 1;
@@ -74,43 +64,60 @@ static int mmap_is_legacy(void)
74 return sysctl_legacy_va_layout; 64 return sysctl_legacy_va_layout;
75} 65}
76 66
67static unsigned long mmap_rnd(void)
68{
69 unsigned long rnd = 0;
70
71 /*
72 * 8 bits of randomness in 32bit mmaps, 20 address space bits
73 * 28 bits of randomness in 64bit mmaps, 40 address space bits
74 */
75 if (current->flags & PF_RANDOMIZE) {
76 if (mmap_is_ia32())
77 rnd = (long)get_random_int() % (1<<8);
78 else
79 rnd = (long)(get_random_int() % (1<<28));
80 }
81 return rnd << PAGE_SHIFT;
82}
83
84static unsigned long mmap_base(void)
85{
86 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
87
88 if (gap < MIN_GAP)
89 gap = MIN_GAP;
90 else if (gap > MAX_GAP)
91 gap = MAX_GAP;
92
93 return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
94}
95
96/*
97 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
98 * does, but not when emulating X86_32
99 */
100static unsigned long mmap_legacy_base(void)
101{
102 if (mmap_is_ia32())
103 return TASK_UNMAPPED_BASE;
104 else
105 return TASK_UNMAPPED_BASE + mmap_rnd();
106}
107
77/* 108/*
78 * This function, called very early during the creation of a new 109 * This function, called very early during the creation of a new
79 * process VM image, sets up which VM layout function to use: 110 * process VM image, sets up which VM layout function to use:
80 */ 111 */
81void arch_pick_mmap_layout(struct mm_struct *mm) 112void arch_pick_mmap_layout(struct mm_struct *mm)
82{ 113{
83 int rnd = 0; 114 if (mmap_is_legacy()) {
84 if (current->flags & PF_RANDOMIZE) { 115 mm->mmap_base = mmap_legacy_base();
85 /*
86 * Add 28bit randomness which is about 40bits of address space
87 * because mmap base has to be page aligned.
88 * or ~1/128 of the total user VM
89 * (total user address space is 47bits)
90 */
91 rnd = get_random_int() & 0xfffffff;
92 }
93
94 /*
95 * Fall back to the standard layout if the personality
96 * bit is set, or if the expected stack growth is unlimited:
97 */
98 if (mmap_is_32()) {
99#ifdef CONFIG_IA32_EMULATION
100 /* ia32_pick_mmap_layout has its own. */
101 return ia32_pick_mmap_layout(mm);
102#endif
103 } else if (mmap_is_legacy()) {
104 mm->mmap_base = TASK_UNMAPPED_BASE;
105 mm->get_unmapped_area = arch_get_unmapped_area; 116 mm->get_unmapped_area = arch_get_unmapped_area;
106 mm->unmap_area = arch_unmap_area; 117 mm->unmap_area = arch_unmap_area;
107 } else { 118 } else {
108 mm->mmap_base = mmap_base(); 119 mm->mmap_base = mmap_base();
109 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 120 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
110 mm->unmap_area = arch_unmap_area_topdown; 121 mm->unmap_area = arch_unmap_area_topdown;
111 if (current->flags & PF_RANDOMIZE)
112 rnd = -rnd;
113 } 122 }
114 if (current->flags & PF_RANDOMIZE)
115 mm->mmap_base += ((long)rnd) << PAGE_SHIFT;
116} 123}
diff --git a/arch/x86/mm/mmap_32.c b/arch/x86/mm/mmap_32.c
deleted file mode 100644
index d490662e4af4..000000000000
--- a/arch/x86/mm/mmap_32.c
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 * linux/arch/i386/mm/mmap.c
3 *
4 * flexible mmap layout support
5 *
6 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
7 * All Rights Reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 *
24 * Started by Ingo Molnar <mingo@elte.hu>
25 */
26
27#include <linux/personality.h>
28#include <linux/mm.h>
29#include <linux/random.h>
30#include <linux/sched.h>
31
32/*
33 * Top of mmap area (just below the process stack).
34 *
35 * Leave an at least ~128 MB hole.
36 */
37#define MIN_GAP (128*1024*1024)
38#define MAX_GAP (TASK_SIZE/6*5)
39
40static inline unsigned long mmap_base(struct mm_struct *mm)
41{
42 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
43 unsigned long random_factor = 0;
44
45 if (current->flags & PF_RANDOMIZE)
46 random_factor = get_random_int() % (1024*1024);
47
48 if (gap < MIN_GAP)
49 gap = MIN_GAP;
50 else if (gap > MAX_GAP)
51 gap = MAX_GAP;
52
53 return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
54}
55
56/*
57 * This function, called very early during the creation of a new
58 * process VM image, sets up which VM layout function to use:
59 */
60#ifdef CONFIG_X86_32
61void arch_pick_mmap_layout(struct mm_struct *mm)
62#else
63void ia32_pick_mmap_layout(struct mm_struct *mm)
64#endif
65{
66 /*
67 * Fall back to the standard layout if the personality
68 * bit is set, or if the expected stack growth is unlimited:
69 */
70 if (sysctl_legacy_va_layout ||
71 (current->personality & ADDR_COMPAT_LAYOUT) ||
72 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
73 mm->mmap_base = TASK_UNMAPPED_BASE;
74 mm->get_unmapped_area = arch_get_unmapped_area;
75 mm->unmap_area = arch_unmap_area;
76 } else {
77 mm->mmap_base = mmap_base(mm);
78 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
79 mm->unmap_area = arch_unmap_area_topdown;
80 }
81}