diff options
| -rw-r--r-- | arch/x86/include/asm/cpufeature.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/intel.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/process.c | 6 | 
3 files changed, 10 insertions, 0 deletions
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index ea408dcba513..7301e60dc4a8 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -93,6 +93,7 @@  #define X86_FEATURE_XTOPOLOGY	(3*32+22) /* cpu topology enum extensions */  #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */  #define X86_FEATURE_NONSTOP_TSC	(3*32+24) /* TSC does not stop in C states */ +#define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */  /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */  #define X86_FEATURE_XMM3	(4*32+ 0) /* "pni" SSE-3 */ diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 430e5c38a544..24ff26a38ade 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -291,6 +291,9 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)  		ds_init_intel(c);  	} +	if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush) +		set_cpu_cap(c, X86_FEATURE_CLFLUSH_MONITOR); +  #ifdef CONFIG_X86_64  	if (c->x86 == 15)  		c->x86_cache_alignment = c->x86_clflush_size * 2; diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index e68bb9e30864..6d12f7e37f8c 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -180,6 +180,9 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx)  	trace_power_start(&it, POWER_CSTATE, (ax>>4)+1);  	if (!need_resched()) { +		if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) +			clflush((void *)¤t_thread_info()->flags); +  		__monitor((void *)¤t_thread_info()->flags, 0, 0);  		smp_mb();  		if (!need_resched()) @@ -194,6 +197,9 @@ static void mwait_idle(void)  	struct power_trace it;  	if (!need_resched()) {  		trace_power_start(&it, POWER_CSTATE, 1); +		if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) +			clflush((void *)¤t_thread_info()->flags); +  		__monitor((void *)¤t_thread_info()->flags, 0, 0);  		smp_mb();  		if (!need_resched())  | 
