mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
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) <peterz@infradead.org> Cc: kevin.b.stanton@intel.com Link: http://lkml.kernel.org/r/20170531155306.050849877@infradead.org Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
c6e9f42bbe
commit
bd9240a18e
1 changed files with 79 additions and 0 deletions
|
@ -54,6 +54,8 @@
|
||||||
#include <asm/mce.h>
|
#include <asm/mce.h>
|
||||||
#include <asm/tsc.h>
|
#include <asm/tsc.h>
|
||||||
#include <asm/hypervisor.h>
|
#include <asm/hypervisor.h>
|
||||||
|
#include <asm/cpu_device_id.h>
|
||||||
|
#include <asm/intel-family.h>
|
||||||
|
|
||||||
unsigned int num_processors;
|
unsigned int num_processors;
|
||||||
|
|
||||||
|
@ -545,6 +547,81 @@ static struct clock_event_device lapic_clockevent = {
|
||||||
};
|
};
|
||||||
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
|
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
|
||||||
|
|
||||||
|
#define DEADLINE_MODEL_MATCH_FUNC(model, func) \
|
||||||
|
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&func }
|
||||||
|
|
||||||
|
#define DEADLINE_MODEL_MATCH_REV(model, rev) \
|
||||||
|
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)rev }
|
||||||
|
|
||||||
|
static u32 hsx_deadline_rev(void)
|
||||||
|
{
|
||||||
|
switch (boot_cpu_data.x86_mask) {
|
||||||
|
case 0x02: return 0x3a; /* EP */
|
||||||
|
case 0x04: return 0x0f; /* EX */
|
||||||
|
}
|
||||||
|
|
||||||
|
return ~0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 bdx_deadline_rev(void)
|
||||||
|
{
|
||||||
|
switch (boot_cpu_data.x86_mask) {
|
||||||
|
case 0x02: return 0x00000011;
|
||||||
|
case 0x03: return 0x0700000e;
|
||||||
|
case 0x04: return 0x0f00000c;
|
||||||
|
case 0x05: return 0x0e000003;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ~0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct x86_cpu_id deadline_match[] = {
|
||||||
|
DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_HASWELL_X, hsx_deadline_rev),
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_X, 0x0b000020),
|
||||||
|
DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_XEON_D, bdx_deadline_rev),
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_X, 0x02000014),
|
||||||
|
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_CORE, 0x22),
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_ULT, 0x20),
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_GT3E, 0x17),
|
||||||
|
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_CORE, 0x25),
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_GT3E, 0x17),
|
||||||
|
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_MOBILE, 0xb2),
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_DESKTOP, 0xb2),
|
||||||
|
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_MOBILE, 0x52),
|
||||||
|
DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_DESKTOP, 0x52),
|
||||||
|
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void apic_check_deadline_errata(void)
|
||||||
|
{
|
||||||
|
const struct x86_cpu_id *m = x86_match_cpu(deadline_match);
|
||||||
|
u32 rev;
|
||||||
|
|
||||||
|
if (!m)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function pointers will have the MSB set due to address layout,
|
||||||
|
* immediate revisions will not.
|
||||||
|
*/
|
||||||
|
if ((long)m->driver_data < 0)
|
||||||
|
rev = ((u32 (*)(void))(m->driver_data))();
|
||||||
|
else
|
||||||
|
rev = (u32)m->driver_data;
|
||||||
|
|
||||||
|
if (boot_cpu_data.microcode >= rev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
|
||||||
|
pr_err(FW_BUG "TSC_DEADLINE disabled due to Errata; "
|
||||||
|
"please update microcode to version: 0x%x (or later)\n", rev);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the local APIC timer for this CPU. Copy the initialized values
|
* Setup the local APIC timer for this CPU. Copy the initialized values
|
||||||
* of the boot CPU and register the clock event in the framework.
|
* of the boot CPU and register the clock event in the framework.
|
||||||
|
@ -1780,6 +1857,8 @@ void __init init_apic_mappings(void)
|
||||||
{
|
{
|
||||||
unsigned int new_apicid;
|
unsigned int new_apicid;
|
||||||
|
|
||||||
|
apic_check_deadline_errata();
|
||||||
|
|
||||||
if (x2apic_mode) {
|
if (x2apic_mode) {
|
||||||
boot_cpu_physical_apicid = read_apic_id();
|
boot_cpu_physical_apicid = read_apic_id();
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue