x86: split NX setup into separate file to limit unstack-protected code
[linux-2.6.git] / arch / x86 / mm / setup_nx.c
1 #include <linux/spinlock.h>
2 #include <linux/errno.h>
3 #include <linux/init.h>
4
5 #include <asm/pgtable.h>
6
7 int nx_enabled;
8
9 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
10 static int disable_nx __cpuinitdata;
11
12 /*
13  * noexec = on|off
14  *
15  * Control non-executable mappings for processes.
16  *
17  * on      Enable
18  * off     Disable
19  */
20 static int __init noexec_setup(char *str)
21 {
22         if (!str)
23                 return -EINVAL;
24         if (!strncmp(str, "on", 2)) {
25                 __supported_pte_mask |= _PAGE_NX;
26                 disable_nx = 0;
27         } else if (!strncmp(str, "off", 3)) {
28                 disable_nx = 1;
29                 __supported_pte_mask &= ~_PAGE_NX;
30         }
31         return 0;
32 }
33 early_param("noexec", noexec_setup);
34 #endif
35
36 #ifdef CONFIG_X86_PAE
37 void __init set_nx(void)
38 {
39         unsigned int v[4], l, h;
40
41         if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
42                 cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
43
44                 if ((v[3] & (1 << 20)) && !disable_nx) {
45                         rdmsr(MSR_EFER, l, h);
46                         l |= EFER_NX;
47                         wrmsr(MSR_EFER, l, h);
48                         nx_enabled = 1;
49                         __supported_pte_mask |= _PAGE_NX;
50                 }
51         }
52 }
53 #else
54 void set_nx(void)
55 {
56 }
57 #endif
58
59 #ifdef CONFIG_X86_64
60 void __cpuinit check_efer(void)
61 {
62         unsigned long efer;
63
64         rdmsrl(MSR_EFER, efer);
65         if (!(efer & EFER_NX) || disable_nx)
66                 __supported_pte_mask &= ~_PAGE_NX;
67 }
68 #endif
69