diff options
-rw-r--r-- | arch/x86/kernel/cpu/amd.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/process_32.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 4 |
4 files changed, 19 insertions, 9 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index cd2fe15ff4b..06fa159232f 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) local_apic_timer_disabled = 1; #endif - if (c->x86 == 0x10 && !force_mwait) - clear_bit(X86_FEATURE_MWAIT, c->x86_capability); - /* K6s reports MCEs but don't actually have all the MSRs */ if (c->x86 < 6) 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 69a69c3f43b..9f45a51af96 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -285,9 +285,17 @@ static void mwait_idle(void) mwait_idle_with_hints(0, 0); } +static int mwait_usable(const struct cpuinfo_x86 *c) +{ + if (force_mwait) + return 1; + /* Any C1 states supported? */ + return c->cpuid_level >= 5 && ((cpuid_edx(5) >> 4) & 0xf) > 0; +} + void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { - if (cpu_has(c, X86_FEATURE_MWAIT)) { + if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) { printk("monitor/mwait feature present.\n"); /* * Skip, if setup has overridden idle. diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 4e65ae8a54b..dbe0a846ec5 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -280,10 +280,19 @@ static void mwait_idle(void) } } + +static int mwait_usable(const struct cpuinfo_x86 *c) +{ + if (force_mwait) + return 1; + /* Any C1 states supported? */ + return c->cpuid_level >= 5 && ((cpuid_edx(5) >> 4) & 0xf) > 0; +} + void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { static int printed; - if (cpu_has(c, X86_FEATURE_MWAIT)) { + if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) { /* * Skip, if setup has overridden idle. * 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 71a420c7fee..4a3f00b4923 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) /* MFENCE stops RDTSC speculation */ set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); - /* Family 10 doesn't support C states in MWAIT so don't use it */ - if (c->x86 == 0x10 && !force_mwait) - clear_cpu_cap(c, X86_FEATURE_MWAIT); - if (amd_apic_timer_broken()) disable_apic_timer = 1; } |