diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-19 21:10:17 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-19 21:10:17 -0400 |
| commit | 5765040ebfc9a28d9dcfaaaaf3d25840d922de96 (patch) | |
| tree | 6fd0c9950beb3c9730ede405269c9a47bbcbf877 | |
| parent | 08839ff8276bd1ba0ce8b2d595f9fe62a5b07210 (diff) | |
| parent | de5397ad5b9ad22e2401c4dacdf1bb3b19c05679 (diff) | |
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
| -rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/cpufeature.h | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/processor-flags.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 23 |
4 files changed, 29 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 259037b873b7..c603ef7b0568 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/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 30afb465d486..5dc6acc98dbd 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
| @@ -195,6 +195,7 @@ | |||
| 195 | 195 | ||
| 196 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ | 196 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ |
| 197 | #define X86_FEATURE_FSGSBASE (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ | 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 | #define X86_FEATURE_ERMS (9*32+ 9) /* Enhanced REP MOVSB/STOSB */ | 199 | #define X86_FEATURE_ERMS (9*32+ 9) /* Enhanced REP MOVSB/STOSB */ |
| 199 | 200 | ||
| 200 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) | 201 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
diff --git a/arch/x86/include/asm/processor-flags.h b/arch/x86/include/asm/processor-flags.h index a898a2b6e10c..59ab4dffa377 100644 --- a/arch/x86/include/asm/processor-flags.h +++ b/arch/x86/include/asm/processor-flags.h | |||
| @@ -60,6 +60,7 @@ | |||
| 60 | #define X86_CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */ | 60 | #define X86_CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */ |
| 61 | #define X86_CR4_VMXE 0x00002000 /* enable VMX virtualization */ | 61 | #define X86_CR4_VMXE 0x00002000 /* enable VMX virtualization */ |
| 62 | #define X86_CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */ | 62 | #define X86_CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */ |
| 63 | #define X86_CR4_SMEP 0x00100000 /* enable SMEP support */ | ||
| 63 | 64 | ||
| 64 | /* | 65 | /* |
| 65 | * x86-64 Task Priority Register, CR8 | 66 | * x86-64 Task Priority Register, CR8 |
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); |
