Commit 5765040ebfc9a28d9dcfaaaaf3d25840d922de96
Exists in
master
and in
7 other branches
Merge branch 'x86-smep-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-smep-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, cpu: Enable/disable Supervisor Mode Execution Protection x86, cpu: Add SMEP CPU feature in CR4 x86, cpufeature: Add cpufeature flag for SMEP
Showing 4 changed files Side-by-side Diff
Documentation/kernel-parameters.txt
... | ... | @@ -1664,6 +1664,10 @@ |
1664 | 1664 | noexec=on: enable non-executable mappings (default) |
1665 | 1665 | noexec=off: disable non-executable mappings |
1666 | 1666 | |
1667 | + nosmep [X86] | |
1668 | + Disable SMEP (Supervisor Mode Execution Protection) | |
1669 | + even if it is supported by processor. | |
1670 | + | |
1667 | 1671 | noexec32 [X86-64] |
1668 | 1672 | This affects only 32-bit executables. |
1669 | 1673 | noexec32=on: enable non-executable mappings (default) |
arch/x86/include/asm/cpufeature.h
... | ... | @@ -195,6 +195,7 @@ |
195 | 195 | |
196 | 196 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ |
197 | 197 | #define X86_FEATURE_FSGSBASE (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ |
198 | +#define X86_FEATURE_SMEP (9*32+ 7) /* Supervisor Mode Execution Protection */ | |
198 | 199 | #define X86_FEATURE_ERMS (9*32+ 9) /* Enhanced REP MOVSB/STOSB */ |
199 | 200 | |
200 | 201 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
arch/x86/include/asm/processor-flags.h
... | ... | @@ -60,6 +60,7 @@ |
60 | 60 | #define X86_CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */ |
61 | 61 | #define X86_CR4_VMXE 0x00002000 /* enable VMX virtualization */ |
62 | 62 | #define X86_CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */ |
63 | +#define X86_CR4_SMEP 0x00100000 /* enable SMEP support */ | |
63 | 64 | |
64 | 65 | /* |
65 | 66 | * x86-64 Task Priority Register, CR8 |
arch/x86/kernel/cpu/common.c
... | ... | @@ -254,6 +254,25 @@ |
254 | 254 | } |
255 | 255 | #endif |
256 | 256 | |
257 | +static int disable_smep __initdata; | |
258 | +static __init int setup_disable_smep(char *arg) | |
259 | +{ | |
260 | + disable_smep = 1; | |
261 | + return 1; | |
262 | +} | |
263 | +__setup("nosmep", setup_disable_smep); | |
264 | + | |
265 | +static __init void setup_smep(struct cpuinfo_x86 *c) | |
266 | +{ | |
267 | + if (cpu_has(c, X86_FEATURE_SMEP)) { | |
268 | + if (unlikely(disable_smep)) { | |
269 | + setup_clear_cpu_cap(X86_FEATURE_SMEP); | |
270 | + clear_in_cr4(X86_CR4_SMEP); | |
271 | + } else | |
272 | + set_in_cr4(X86_CR4_SMEP); | |
273 | + } | |
274 | +} | |
275 | + | |
257 | 276 | /* |
258 | 277 | * Some CPU features depend on higher CPUID levels, which may not always |
259 | 278 | * be available due to CPUID level capping or broken virtualization |
... | ... | @@ -667,6 +686,8 @@ |
667 | 686 | c->cpu_index = 0; |
668 | 687 | #endif |
669 | 688 | filter_cpuid_features(c, false); |
689 | + | |
690 | + setup_smep(c); | |
670 | 691 | } |
671 | 692 | |
672 | 693 | void __init early_cpu_init(void) |
... | ... | @@ -751,6 +772,8 @@ |
751 | 772 | c->phys_proc_id = c->initial_apicid; |
752 | 773 | #endif |
753 | 774 | } |
775 | + | |
776 | + setup_smep(c); | |
754 | 777 | |
755 | 778 | get_model_name(c); /* Default name */ |
756 | 779 |