aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Enberg <penberg@cs.helsinki.fi>2009-04-21 04:39:27 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-21 04:48:08 -0400
commit89388913f2c88a2cd15d24abab571b17a2596127 (patch)
tree2d3791f3fe4b844ba007371c2fe203b304e4c2cc
parent8ecee4620e76aae418bfa0e8cc830e92cb559bbb (diff)
x86: unify noexec handling
This patch unifies noexec handling on 32-bit and 64-bit. [ Impact: cleanup ] Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi> [ mingo@elte.hu: build fix ] LKML-Reference: <1240303167.771.69.camel@penberg-laptop> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/include/asm/pgtable_types.h1
-rw-r--r--arch/x86/mm/init.c67
-rw-r--r--arch/x86/mm/init_32.c52
-rw-r--r--arch/x86/mm/init_64.c33
4 files changed, 63 insertions, 90 deletions
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index b8238dc8786d..4d258ad76a0f 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -273,7 +273,6 @@ typedef struct page *pgtable_t;
273 273
274extern pteval_t __supported_pte_mask; 274extern pteval_t __supported_pte_mask;
275extern int nx_enabled; 275extern int nx_enabled;
276extern void set_nx(void);
277 276
278#define pgprot_writecombine pgprot_writecombine 277#define pgprot_writecombine pgprot_writecombine
279extern pgprot_t pgprot_writecombine(pgprot_t prot); 278extern pgprot_t pgprot_writecombine(pgprot_t prot);
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index fd3da1dda1c9..fedde5359a04 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -22,6 +22,69 @@ int direct_gbpages
22#endif 22#endif
23; 23;
24 24
25int nx_enabled;
26
27#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
28static int disable_nx __cpuinitdata;
29
30/*
31 * noexec = on|off
32 *
33 * Control non-executable mappings for processes.
34 *
35 * on Enable
36 * off Disable
37 */
38static int __init noexec_setup(char *str)
39{
40 if (!str)
41 return -EINVAL;
42 if (!strncmp(str, "on", 2)) {
43 __supported_pte_mask |= _PAGE_NX;
44 disable_nx = 0;
45 } else if (!strncmp(str, "off", 3)) {
46 disable_nx = 1;
47 __supported_pte_mask &= ~_PAGE_NX;
48 }
49 return 0;
50}
51early_param("noexec", noexec_setup);
52#endif
53
54#ifdef CONFIG_X86_PAE
55static void __init set_nx(void)
56{
57 unsigned int v[4], l, h;
58
59 if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
60 cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
61
62 if ((v[3] & (1 << 20)) && !disable_nx) {
63 rdmsr(MSR_EFER, l, h);
64 l |= EFER_NX;
65 wrmsr(MSR_EFER, l, h);
66 nx_enabled = 1;
67 __supported_pte_mask |= _PAGE_NX;
68 }
69 }
70}
71#else
72static inline void set_nx(void)
73{
74}
75#endif
76
77#ifdef CONFIG_X86_64
78void __cpuinit check_efer(void)
79{
80 unsigned long efer;
81
82 rdmsrl(MSR_EFER, efer);
83 if (!(efer & EFER_NX) || disable_nx)
84 __supported_pte_mask &= ~_PAGE_NX;
85}
86#endif
87
25static void __init find_early_table_space(unsigned long end, int use_pse, 88static void __init find_early_table_space(unsigned long end, int use_pse,
26 int use_gbpages) 89 int use_gbpages)
27{ 90{
@@ -158,12 +221,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
158 use_gbpages = direct_gbpages; 221 use_gbpages = direct_gbpages;
159#endif 222#endif
160 223
161#ifdef CONFIG_X86_32
162#ifdef CONFIG_X86_PAE
163 set_nx(); 224 set_nx();
164 if (nx_enabled) 225 if (nx_enabled)
165 printk(KERN_INFO "NX (Execute Disable) protection: active\n"); 226 printk(KERN_INFO "NX (Execute Disable) protection: active\n");
166#endif
167 227
168 /* Enable PSE if available */ 228 /* Enable PSE if available */
169 if (cpu_has_pse) 229 if (cpu_has_pse)
@@ -174,7 +234,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
174 set_in_cr4(X86_CR4_PGE); 234 set_in_cr4(X86_CR4_PGE);
175 __supported_pte_mask |= _PAGE_GLOBAL; 235 __supported_pte_mask |= _PAGE_GLOBAL;
176 } 236 }
177#endif
178 237
179 if (use_gbpages) 238 if (use_gbpages)
180 page_size_mask |= 1 << PG_LEVEL_1G; 239 page_size_mask |= 1 << PG_LEVEL_1G;
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 749559ed80f5..2b27120665b3 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -587,61 +587,9 @@ void zap_low_mappings(void)
587 flush_tlb_all(); 587 flush_tlb_all();
588} 588}
589 589
590int nx_enabled;
591
592pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP); 590pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
593EXPORT_SYMBOL_GPL(__supported_pte_mask); 591EXPORT_SYMBOL_GPL(__supported_pte_mask);
594 592
595#ifdef CONFIG_X86_PAE
596
597static int disable_nx __initdata;
598
599/*
600 * noexec = on|off
601 *
602 * Control non executable mappings.
603 *
604 * on Enable
605 * off Disable
606 */
607static int __init noexec_setup(char *str)
608{
609 if (!str || !strcmp(str, "on")) {
610 if (cpu_has_nx) {
611 __supported_pte_mask |= _PAGE_NX;
612 disable_nx = 0;
613 }
614 } else {
615 if (!strcmp(str, "off")) {
616 disable_nx = 1;
617 __supported_pte_mask &= ~_PAGE_NX;
618 } else {
619 return -EINVAL;
620 }
621 }
622
623 return 0;
624}
625early_param("noexec", noexec_setup);
626
627void __init set_nx(void)
628{
629 unsigned int v[4], l, h;
630
631 if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
632 cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
633
634 if ((v[3] & (1 << 20)) && !disable_nx) {
635 rdmsr(MSR_EFER, l, h);
636 l |= EFER_NX;
637 wrmsr(MSR_EFER, l, h);
638 nx_enabled = 1;
639 __supported_pte_mask |= _PAGE_NX;
640 }
641 }
642}
643#endif
644
645/* user-defined highmem size */ 593/* user-defined highmem size */
646static unsigned int highmem_pages = -1; 594static unsigned int highmem_pages = -1;
647 595
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 1753e8020df6..a4e7846efb1a 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -85,39 +85,6 @@ early_param("gbpages", parse_direct_gbpages_on);
85pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP; 85pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
86EXPORT_SYMBOL_GPL(__supported_pte_mask); 86EXPORT_SYMBOL_GPL(__supported_pte_mask);
87 87
88static int disable_nx __cpuinitdata;
89
90/*
91 * noexec=on|off
92 * Control non-executable mappings for 64-bit processes.
93 *
94 * on Enable (default)
95 * off Disable
96 */
97static int __init nonx_setup(char *str)
98{
99 if (!str)
100 return -EINVAL;
101 if (!strncmp(str, "on", 2)) {
102 __supported_pte_mask |= _PAGE_NX;
103 disable_nx = 0;
104 } else if (!strncmp(str, "off", 3)) {
105 disable_nx = 1;
106 __supported_pte_mask &= ~_PAGE_NX;
107 }
108 return 0;
109}
110early_param("noexec", nonx_setup);
111
112void __cpuinit check_efer(void)
113{
114 unsigned long efer;
115
116 rdmsrl(MSR_EFER, efer);
117 if (!(efer & EFER_NX) || disable_nx)
118 __supported_pte_mask &= ~_PAGE_NX;
119}
120
121int force_personality32; 88int force_personality32;
122 89
123/* 90/*