Commit | Line | Data |
---|---|---|
c44c9ec0 JF |
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 |