diff --git a/[refs] b/[refs] index 13ac7464005e..f1ec3a22ecce 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 63bcff2a307b9bcc712a8251eb27df8b2e117967 +refs/heads/master: 52b6179ac87d33c2eeaff5292786a10fe98cff64 diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index ad7e2e5088c1..49c5c41b07e1 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1812,8 +1812,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. noexec=on: enable non-executable mappings (default) noexec=off: disable non-executable mappings + nosmap [X86] + Disable SMAP (Supervisor Mode Access Prevention) + even if it is supported by processor. + nosmep [X86] - Disable SMEP (Supervisor Mode Execution Protection) + Disable SMEP (Supervisor Mode Execution Prevention) even if it is supported by processor. noexec32 [X86-64] diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index cd43e525fde8..7d35d6594118 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -278,6 +278,31 @@ static __cpuinit void setup_smep(struct cpuinfo_x86 *c) } } +static int disable_smap __cpuinitdata; +static __init int setup_disable_smap(char *arg) +{ + disable_smap = 1; + return 1; +} +__setup("nosmap", setup_disable_smap); + +static __cpuinit void setup_smap(struct cpuinfo_x86 *c) +{ + if (cpu_has(c, X86_FEATURE_SMAP)) { + if (unlikely(disable_smap)) { + setup_clear_cpu_cap(X86_FEATURE_SMAP); + clear_in_cr4(X86_CR4_SMAP); + } else { + set_in_cr4(X86_CR4_SMAP); + /* + * Don't use clac() here since alternatives + * haven't run yet... + */ + asm volatile(__stringify(__ASM_CLAC) ::: "memory"); + } + } +} + /* * Some CPU features depend on higher CPUID levels, which may not always * be available due to CPUID level capping or broken virtualization @@ -713,6 +738,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) filter_cpuid_features(c, false); setup_smep(c); + setup_smap(c); if (this_cpu->c_bsp_init) this_cpu->c_bsp_init(c);