Skip to content

Commit

Permalink
i386: Use global flag to disable broken local apic timer on AMD CPUs.
Browse files Browse the repository at this point in the history
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
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Aug 11, 2007
1 parent d2d0251 commit d3f7eae
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 8 deletions.
10 changes: 4 additions & 6 deletions arch/i386/kernel/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -370,12 +371,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.
*/
Expand Down
7 changes: 6 additions & 1 deletion arch/i386/kernel/cpu/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/apic.h>

#include "cpu.h"

Expand All @@ -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
Expand Down Expand Up @@ -52,6 +54,7 @@ static __cpuinit int amd_apic_timer_broken(void)
}
return 0;
}
#endif

int force_mwait __cpuinitdata;

Expand Down Expand Up @@ -282,8 +285,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
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);
Expand Down
2 changes: 2 additions & 0 deletions include/asm-i386/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ extern void enable_NMI_through_LVT0 (void * dummy);
extern int timer_over_8254;
extern int local_apic_timer_c2_ok;

extern int local_apic_timer_disabled;

#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }

Expand Down
2 changes: 1 addition & 1 deletion include/asm-i386/cpufeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
#define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
#define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */
#define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */
#define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
/* 14 free */
#define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */
#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */

Expand Down

0 comments on commit d3f7eae

Please sign in to comment.