Commit 5765040ebfc9a28d9dcfaaaaf3d25840d922de96

Authored by Linus Torvalds

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