x86: disable apic timer for AMD C1E enabled CPUs
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>
This commit is contained in:
parent
4e77ae3e10
commit
fb79d22e1d
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue