Skip to content

Commit

Permalink
x86: disable apic timer for AMD C1E enabled CPUs
Browse files Browse the repository at this point in the history
AMDs C1E enabled CPUs stop the local apic timer, when both cores are
idle. This is a hardware feature which breaks highres/dynticks.
Add the same quirk as we have for 32 bit already.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
  • Loading branch information
Thomas Gleixner authored and Thomas Gleixner committed Oct 12, 2007
1 parent 4e77ae3 commit fb79d22
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
2 changes: 1 addition & 1 deletion arch/x86/kernel/apic_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int apic_verbosity;
int apic_runs_main_timer;
int apic_calibrate_pmtmr __initdata;

int disable_apic_timer __initdata;
int disable_apic_timer __cpuinitdata;

/* Local APIC timer works in C2? */
int local_apic_timer_c2_ok;
Expand Down
34 changes: 34 additions & 0 deletions arch/x86/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,37 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
#endif
}

#define ENABLE_C1E_MASK 0x18000000
#define CPUID_PROCESSOR_SIGNATURE 1
#define CPUID_XFAM 0x0ff00000
#define CPUID_XFAM_K8 0x00000000
#define CPUID_XFAM_10H 0x00100000
#define CPUID_XFAM_11H 0x00200000
#define CPUID_XMOD 0x000f0000
#define CPUID_XMOD_REV_F 0x00040000

/* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
static __cpuinit int amd_apic_timer_broken(void)
{
u32 lo, hi;
u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
switch (eax & CPUID_XFAM) {
case CPUID_XFAM_K8:
if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F)
break;
case CPUID_XFAM_10H:
case CPUID_XFAM_11H:
rdmsr(MSR_K8_ENABLE_C1E, lo, hi);
if (lo & ENABLE_C1E_MASK)
return 1;
break;
default:
/* err on the side of caution */
return 1;
}
return 0;
}

static void __cpuinit init_amd(struct cpuinfo_x86 *c)
{
unsigned level;
Expand Down Expand Up @@ -617,6 +648,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
/* Family 10 doesn't support C states in MWAIT so don't use it */
if (c->x86 == 0x10 && !force_mwait)
clear_bit(X86_FEATURE_MWAIT, &c->x86_capability);

if (amd_apic_timer_broken())
disable_apic_timer = 1;
}

static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
Expand Down
1 change: 1 addition & 0 deletions include/asm-x86/apic_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
extern int apic_verbosity;
extern int apic_runs_main_timer;
extern int ioapic_force;
extern int disable_apic_timer;

/*
* Define the default level of output to be very little
Expand Down

0 comments on commit fb79d22

Please sign in to comment.