Commit de5397ad5b9ad22e2401c4dacdf1bb3b19c05679
Committed by
H. Peter Anvin
1 parent
dc23c0bccf
Exists in
master
and in
4 other branches
x86, cpu: Enable/disable Supervisor Mode Execution Protection
Enable/disable newly documented SMEP (Supervisor Mode Execution Protection) CPU feature in kernel. CR4.SMEP (bit 20) is 0 at power-on. If the feature is supported by CPU (X86_FEATURE_SMEP), enable SMEP by setting CR4.SMEP. New kernel option nosmep disables the feature even if the feature is supported by CPU. [ hpa: moved the call to setup_smep() until after the vendor-specific initialization; that ensures that CPUID features are unmasked. We will still run it before we have userspace (never mind uncontrolled userspace). ] Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> LKML-Reference: <1305157865-31727-1-git-send-email-fenghua.yu@intel.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Showing 2 changed files with 27 additions and 0 deletions 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/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 |