aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2008-01-30 07:33:16 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:33:16 -0500
commit0c07ee38c9d4eb081758f5ad14bbffa7197e1aec (patch)
treef32f5dba9b03b9fa5ac262a2c569b43ae9d0994e /arch
parent30d432dfab2bcfd021d352e2058fae6b9405caeb (diff)
x86: use the correct cpuid method to detect MWAIT support for C states
Previously there was a AMD specific quirk to handle the case of AMD Fam10h MWAIT not supporting any C states. But it turns out that CPUID already has ways to detectly detect that without using special quirks. The new code simply checks if MWAIT supports at least C1 and doesn't use it if it doesn't. No more vendor specific code. Note this is does not simply clear MWAIT because MWAIT can be still useful even without C states. Credit goes to Ben Serebrin for pointing out the (nearly) obvious. Cc: "Andreas Herrmann" <andreas.herrmann3@amd.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/amd.c3
-rw-r--r--arch/x86/kernel/process_32.c10
-rw-r--r--arch/x86/kernel/process_64.c11
-rw-r--r--arch/x86/kernel/setup_64.c4
4 files changed, 19 insertions, 9 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index cd2fe15ff4b5..06fa159232fd 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -300,9 +300,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
300 local_apic_timer_disabled = 1; 300 local_apic_timer_disabled = 1;
301#endif 301#endif
302 302
303 if (c->x86 == 0x10 && !force_mwait)
304 clear_bit(X86_FEATURE_MWAIT, c->x86_capability);
305
306 /* K6s reports MCEs but don't actually have all the MSRs */ 303 /* K6s reports MCEs but don't actually have all the MSRs */
307 if (c->x86 < 6) 304 if (c->x86 < 6)
308 clear_bit(X86_FEATURE_MCE, c->x86_capability); 305 clear_bit(X86_FEATURE_MCE, c->x86_capability);
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 69a69c3f43bb..9f45a51af968 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -285,9 +285,17 @@ static void mwait_idle(void)
285 mwait_idle_with_hints(0, 0); 285 mwait_idle_with_hints(0, 0);
286} 286}
287 287
288static int mwait_usable(const struct cpuinfo_x86 *c)
289{
290 if (force_mwait)
291 return 1;
292 /* Any C1 states supported? */
293 return c->cpuid_level >= 5 && ((cpuid_edx(5) >> 4) & 0xf) > 0;
294}
295
288void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 296void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
289{ 297{
290 if (cpu_has(c, X86_FEATURE_MWAIT)) { 298 if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) {
291 printk("monitor/mwait feature present.\n"); 299 printk("monitor/mwait feature present.\n");
292 /* 300 /*
293 * Skip, if setup has overridden idle. 301 * Skip, if setup has overridden idle.
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 4e65ae8a54bf..dbe0a846ec52 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -280,10 +280,19 @@ static void mwait_idle(void)
280 } 280 }
281} 281}
282 282
283
284static int mwait_usable(const struct cpuinfo_x86 *c)
285{
286 if (force_mwait)
287 return 1;
288 /* Any C1 states supported? */
289 return c->cpuid_level >= 5 && ((cpuid_edx(5) >> 4) & 0xf) > 0;
290}
291
283void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 292void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
284{ 293{
285 static int printed; 294 static int printed;
286 if (cpu_has(c, X86_FEATURE_MWAIT)) { 295 if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) {
287 /* 296 /*
288 * Skip, if setup has overridden idle. 297 * Skip, if setup has overridden idle.
289 * One CPU supports mwait => All CPUs supports mwait 298 * One CPU supports mwait => All CPUs supports mwait
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 71a420c7fee7..4a3f00b49236 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -761,10 +761,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
761 /* MFENCE stops RDTSC speculation */ 761 /* MFENCE stops RDTSC speculation */
762 set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); 762 set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
763 763
764 /* Family 10 doesn't support C states in MWAIT so don't use it */
765 if (c->x86 == 0x10 && !force_mwait)
766 clear_cpu_cap(c, X86_FEATURE_MWAIT);
767
768 if (amd_apic_timer_broken()) 764 if (amd_apic_timer_broken())
769 disable_apic_timer = 1; 765 disable_apic_timer = 1;
770} 766}