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); |
