diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 23 |
2 files changed, 27 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cc85a9278190..56fb8c16e20b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1664,6 +1664,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1664 | noexec=on: enable non-executable mappings (default) | 1664 | noexec=on: enable non-executable mappings (default) |
1665 | noexec=off: disable non-executable mappings | 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 | noexec32 [X86-64] | 1671 | noexec32 [X86-64] |
1668 | This affects only 32-bit executables. | 1672 | This affects only 32-bit executables. |
1669 | noexec32=on: enable non-executable mappings (default) | 1673 | noexec32=on: enable non-executable mappings (default) |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 173f3a3fa1a6..cbc70a27430c 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -254,6 +254,25 @@ static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) | |||
254 | } | 254 | } |
255 | #endif | 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 | * Some CPU features depend on higher CPUID levels, which may not always | 277 | * Some CPU features depend on higher CPUID levels, which may not always |
259 | * be available due to CPUID level capping or broken virtualization | 278 | * be available due to CPUID level capping or broken virtualization |
@@ -667,6 +686,8 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
667 | c->cpu_index = 0; | 686 | c->cpu_index = 0; |
668 | #endif | 687 | #endif |
669 | filter_cpuid_features(c, false); | 688 | filter_cpuid_features(c, false); |
689 | |||
690 | setup_smep(c); | ||
670 | } | 691 | } |
671 | 692 | ||
672 | void __init early_cpu_init(void) | 693 | void __init early_cpu_init(void) |
@@ -752,6 +773,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c) | |||
752 | #endif | 773 | #endif |
753 | } | 774 | } |
754 | 775 | ||
776 | setup_smep(c); | ||
777 | |||
755 | get_model_name(c); /* Default name */ | 778 | get_model_name(c); /* Default name */ |
756 | 779 | ||
757 | detect_nopl(c); | 780 | detect_nopl(c); |