Skip to content

Commit bd9240a

Browse files
Peter ZijlstraKAGA-KOKO
authored andcommitted
x86/apic: Add TSC_DEADLINE quirk due to errata
Due to errata it is possible for the TSC_DEADLINE timer to misbehave after using TSC_ADJUST. A microcode update is available to fix this situation. Avoid using the TSC_DEADLINE timer if it is affected by this issue and report the required microcode version. [ tglx: Renamed function to apic_check_deadline_errata() ] Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Thomas Gleixner <[email protected]>
1 parent c6e9f42 commit bd9240a

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

arch/x86/kernel/apic/apic.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
#include <asm/mce.h>
5555
#include <asm/tsc.h>
5656
#include <asm/hypervisor.h>
57+
#include <asm/cpu_device_id.h>
58+
#include <asm/intel-family.h>
5759

5860
unsigned int num_processors;
5961

@@ -545,6 +547,81 @@ static struct clock_event_device lapic_clockevent = {
545547
};
546548
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
547549

550+
#define DEADLINE_MODEL_MATCH_FUNC(model, func) \
551+
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&func }
552+
553+
#define DEADLINE_MODEL_MATCH_REV(model, rev) \
554+
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)rev }
555+
556+
static u32 hsx_deadline_rev(void)
557+
{
558+
switch (boot_cpu_data.x86_mask) {
559+
case 0x02: return 0x3a; /* EP */
560+
case 0x04: return 0x0f; /* EX */
561+
}
562+
563+
return ~0U;
564+
}
565+
566+
static u32 bdx_deadline_rev(void)
567+
{
568+
switch (boot_cpu_data.x86_mask) {
569+
case 0x02: return 0x00000011;
570+
case 0x03: return 0x0700000e;
571+
case 0x04: return 0x0f00000c;
572+
case 0x05: return 0x0e000003;
573+
}
574+
575+
return ~0U;
576+
}
577+
578+
static const struct x86_cpu_id deadline_match[] = {
579+
DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_HASWELL_X, hsx_deadline_rev),
580+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_X, 0x0b000020),
581+
DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_XEON_D, bdx_deadline_rev),
582+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_X, 0x02000014),
583+
584+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_CORE, 0x22),
585+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_ULT, 0x20),
586+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_GT3E, 0x17),
587+
588+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_CORE, 0x25),
589+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_GT3E, 0x17),
590+
591+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_MOBILE, 0xb2),
592+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_DESKTOP, 0xb2),
593+
594+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_MOBILE, 0x52),
595+
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_DESKTOP, 0x52),
596+
597+
{},
598+
};
599+
600+
static void apic_check_deadline_errata(void)
601+
{
602+
const struct x86_cpu_id *m = x86_match_cpu(deadline_match);
603+
u32 rev;
604+
605+
if (!m)
606+
return;
607+
608+
/*
609+
* Function pointers will have the MSB set due to address layout,
610+
* immediate revisions will not.
611+
*/
612+
if ((long)m->driver_data < 0)
613+
rev = ((u32 (*)(void))(m->driver_data))();
614+
else
615+
rev = (u32)m->driver_data;
616+
617+
if (boot_cpu_data.microcode >= rev)
618+
return;
619+
620+
setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
621+
pr_err(FW_BUG "TSC_DEADLINE disabled due to Errata; "
622+
"please update microcode to version: 0x%x (or later)\n", rev);
623+
}
624+
548625
/*
549626
* Setup the local APIC timer for this CPU. Copy the initialized values
550627
* of the boot CPU and register the clock event in the framework.
@@ -1780,6 +1857,8 @@ void __init init_apic_mappings(void)
17801857
{
17811858
unsigned int new_apicid;
17821859

1860+
apic_check_deadline_errata();
1861+
17831862
if (x2apic_mode) {
17841863
boot_cpu_physical_apicid = read_apic_id();
17851864
return;

0 commit comments

Comments
 (0)