aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/init.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-10 19:13:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-10 19:13:20 -0400
commitbb7762961d3ce745688e9050e914c1d3f980268d (patch)
treee841f58cd6188cc44583cd055798b4475a4d68f0 /arch/x86/mm/init.c
parent48c72d1ab4ec86789a23aed0b0b5f31ac083c0c6 (diff)
parent35d5a9a61490bf39d2e48d7f499c8c801a39ebe9 (diff)
Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (22 commits) x86: fix system without memory on node0 x86, mm: Fix node_possible_map logic mm, x86: remove MEMORY_HOTPLUG_RESERVE related code x86: make sparse mem work in non-NUMA mode x86: process.c, remove useless headers x86: merge process.c a bit x86: use sparse_memory_present_with_active_regions() on UMA x86: unify 64-bit UMA and NUMA paging_init() x86: Allow 1MB of slack between the e820 map and SRAT, not 4GB x86: Sanity check the e820 against the SRAT table using e820 map only x86: clean up and and print out initial max_pfn_mapped x86/pci: remove rounding quirk from e820_setup_gap() x86, e820, pci: reserve extra free space near end of RAM x86: fix typo in address space documentation x86: 46 bit physical address support on 64 bits x86, mm: fault.c, use printk_once() in is_errata93() x86: move per-cpu mmu_gathers to mm/init.c x86: move max_pfn_mapped and max_low_pfn_mapped to setup.c x86: unify noexec handling x86: remove (null) in /sys kernel_page_tables ...
Diffstat (limited to 'arch/x86/mm/init.c')
-rw-r--r--arch/x86/mm/init.c77
1 files changed, 69 insertions, 8 deletions
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 4b98df0973b9..34c1bfb64f1c 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -11,6 +11,9 @@
11#include <asm/setup.h> 11#include <asm/setup.h>
12#include <asm/system.h> 12#include <asm/system.h>
13#include <asm/tlbflush.h> 13#include <asm/tlbflush.h>
14#include <asm/tlb.h>
15
16DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
14 17
15unsigned long __initdata e820_table_start; 18unsigned long __initdata e820_table_start;
16unsigned long __meminitdata e820_table_end; 19unsigned long __meminitdata e820_table_end;
@@ -24,6 +27,69 @@ int direct_gbpages
24#endif 27#endif
25; 28;
26 29
30int nx_enabled;
31
32#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
33static int disable_nx __cpuinitdata;
34
35/*
36 * noexec = on|off
37 *
38 * Control non-executable mappings for processes.
39 *
40 * on Enable
41 * off Disable
42 */
43static int __init noexec_setup(char *str)
44{
45 if (!str)
46 return -EINVAL;
47 if (!strncmp(str, "on", 2)) {
48 __supported_pte_mask |= _PAGE_NX;
49 disable_nx = 0;
50 } else if (!strncmp(str, "off", 3)) {
51 disable_nx = 1;
52 __supported_pte_mask &= ~_PAGE_NX;
53 }
54 return 0;
55}
56early_param("noexec", noexec_setup);
57#endif
58
59#ifdef CONFIG_X86_PAE
60static void __init set_nx(void)
61{
62 unsigned int v[4], l, h;
63
64 if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
65 cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
66
67 if ((v[3] & (1 << 20)) && !disable_nx) {
68 rdmsr(MSR_EFER, l, h);
69 l |= EFER_NX;
70 wrmsr(MSR_EFER, l, h);
71 nx_enabled = 1;
72 __supported_pte_mask |= _PAGE_NX;
73 }
74 }
75}
76#else
77static inline void set_nx(void)
78{
79}
80#endif
81
82#ifdef CONFIG_X86_64
83void __cpuinit check_efer(void)
84{
85 unsigned long efer;
86
87 rdmsrl(MSR_EFER, efer);
88 if (!(efer & EFER_NX) || disable_nx)
89 __supported_pte_mask &= ~_PAGE_NX;
90}
91#endif
92
27static void __init find_early_table_space(unsigned long end, int use_pse, 93static void __init find_early_table_space(unsigned long end, int use_pse,
28 int use_gbpages) 94 int use_gbpages)
29{ 95{
@@ -67,12 +133,11 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
67 */ 133 */
68#ifdef CONFIG_X86_32 134#ifdef CONFIG_X86_32
69 start = 0x7000; 135 start = 0x7000;
70 e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT, 136#else
71 tables, PAGE_SIZE);
72#else /* CONFIG_X86_64 */
73 start = 0x8000; 137 start = 0x8000;
74 e820_table_start = find_e820_area(start, end, tables, PAGE_SIZE);
75#endif 138#endif
139 e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
140 tables, PAGE_SIZE);
76 if (e820_table_start == -1UL) 141 if (e820_table_start == -1UL)
77 panic("Cannot find space for the kernel page tables"); 142 panic("Cannot find space for the kernel page tables");
78 143
@@ -160,12 +225,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
160 use_gbpages = direct_gbpages; 225 use_gbpages = direct_gbpages;
161#endif 226#endif
162 227
163#ifdef CONFIG_X86_32
164#ifdef CONFIG_X86_PAE
165 set_nx(); 228 set_nx();
166 if (nx_enabled) 229 if (nx_enabled)
167 printk(KERN_INFO "NX (Execute Disable) protection: active\n"); 230 printk(KERN_INFO "NX (Execute Disable) protection: active\n");
168#endif
169 231
170 /* Enable PSE if available */ 232 /* Enable PSE if available */
171 if (cpu_has_pse) 233 if (cpu_has_pse)
@@ -176,7 +238,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
176 set_in_cr4(X86_CR4_PGE); 238 set_in_cr4(X86_CR4_PGE);
177 __supported_pte_mask |= _PAGE_GLOBAL; 239 __supported_pte_mask |= _PAGE_GLOBAL;
178 } 240 }
179#endif
180 241
181 if (use_gbpages) 242 if (use_gbpages)
182 page_size_mask |= 1 << PG_LEVEL_1G; 243 page_size_mask |= 1 << PG_LEVEL_1G;