diff options
author | Andi Kleen <ak@suse.de> | 2007-08-10 22:31:07 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-10 10:50:17 -0700 |
commit | b44da25c30867fa71f2cec3334ecfa1e9412dab4 (patch) | |
tree | 5e954b63b6badef8d2cf3a317f3e9edf57e0462c /arch | |
parent | 880da58fc49a4e021d49b4aeae3b2c6b51e211fa (diff) | |
download | kernel-common-b44da25c30867fa71f2cec3334ecfa1e9412dab4.tar.gz kernel-common-b44da25c30867fa71f2cec3334ecfa1e9412dab4.tar.bz2 kernel-common-b44da25c30867fa71f2cec3334ecfa1e9412dab4.zip |
i386: Use global flag to disable broken local apic timer on AMD CPUs.
commit d3f7eae182b04997be19343a23f7009170f4f7a5 upstream
The Averatec 2370 and some other Turion laptop BIOS seems to program the
ENABLE_C1E MSR inconsistently between cores. This confuses the lapic
use heuristics because when C1E is enabled anywhere it seems to affect
the complete chip.
Use a global flag instead of a per cpu flag to handle this.
If any CPU has C1E enabled disabled lapic use.
Thanks to Cal Peake for debugging.
Cc: tglx@linutronix.de
Cc: Chuck Ebbert <cebbert@redhat.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/apic.c | 10 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/amd.c | 7 |
2 files changed, 10 insertions, 7 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 67824f3bb974..a8ceb7a290ec 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -61,8 +61,9 @@ static int enable_local_apic __initdata = 0; /* Local APIC timer verification ok */ static int local_apic_timer_verify_ok; -/* Disable local APIC timer from the kernel commandline or via dmi quirk */ -static int local_apic_timer_disabled; +/* Disable local APIC timer from the kernel commandline or via dmi quirk + or using CPU MSR check */ +int local_apic_timer_disabled; /* Local APIC timer works in C2 */ int local_apic_timer_c2_ok; EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); @@ -367,12 +368,9 @@ void __init setup_boot_APIC_clock(void) long delta, deltapm; int pm_referenced = 0; - if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN)) - local_apic_timer_disabled = 1; - /* * The local apic timer can be disabled via the kernel - * commandline or from the test above. Register the lapic + * commandline or from the CPU detection code. Register the lapic * timer as a dummy clock event source on SMP systems, so the * broadcast mechanism is used. On UP systems simply ignore it. */ diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 6f47eeeb93ea..9d23390e4bea 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -3,6 +3,7 @@ #include <linux/mm.h> #include <asm/io.h> #include <asm/processor.h> +#include <asm/apic.h> #include "cpu.h" @@ -22,6 +23,7 @@ extern void vide(void); __asm__(".align 4\nvide: ret"); +#ifdef CONFIG_X86_LOCAL_APIC #define ENABLE_C1E_MASK 0x18000000 #define CPUID_PROCESSOR_SIGNATURE 1 #define CPUID_XFAM 0x0ff00000 @@ -52,6 +54,7 @@ static __cpuinit int amd_apic_timer_broken(void) } return 0; } +#endif int force_mwait __cpuinitdata; @@ -275,8 +278,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) if (cpuid_eax(0x80000000) >= 0x80000006) num_cache_leaves = 3; +#ifdef CONFIG_X86_LOCAL_APIC if (amd_apic_timer_broken()) - set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); + local_apic_timer_disabled = 1; +#endif if (c->x86 == 0x10 && !force_mwait) clear_bit(X86_FEATURE_MWAIT, c->x86_capability); |