diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 26 | 
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index e2ced0074a4..c8b41623377 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)  }  #endif +static int disable_smep __cpuinitdata; +static __init int setup_disable_smep(char *arg) +{ +	disable_smep = 1; +	return 1; +} +__setup("nosmep", setup_disable_smep); + +static __cpuinit void setup_smep(struct cpuinfo_x86 *c) +{ +	if (cpu_has(c, X86_FEATURE_SMEP)) { +		if (unlikely(disable_smep)) { +			setup_clear_cpu_cap(X86_FEATURE_SMEP); +			clear_in_cr4(X86_CR4_SMEP); +		} else +			set_in_cr4(X86_CR4_SMEP); +	} +} +  /*   * Some CPU features depend on higher CPUID levels, which may not always   * be available due to CPUID level capping or broken virtualization @@ -565,8 +584,7 @@ void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)  		cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx); -		if (eax > 0) -			c->x86_capability[9] = ebx; +		c->x86_capability[9] = ebx;  	}  	/* AMD-defined flags: level 0x80000001 */ @@ -668,6 +686,8 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)  	c->cpu_index = 0;  #endif  	filter_cpuid_features(c, false); + +	setup_smep(c);  }  void __init early_cpu_init(void) @@ -753,6 +773,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)  #endif  	} +	setup_smep(c); +  	get_model_name(c); /* Default name */  	detect_nopl(c);  |