| From foo@baz Wed Feb 7 19:38:23 CST 2018 |
| From: David Woodhouse <dwmw@amazon.co.uk> |
| Date: Thu, 25 Jan 2018 16:14:14 +0000 |
| Subject: x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes |
| |
| From: David Woodhouse <dwmw@amazon.co.uk> |
| |
| (cherry picked from commit a5b2966364538a0e68c9fa29bc0a3a1651799035) |
| |
| This doesn't refuse to load the affected microcodes; it just refuses to |
| use the Spectre v2 mitigation features if they're detected, by clearing |
| the appropriate feature bits. |
| |
| The AMD CPUID bits are handled here too, because hypervisors *may* have |
| been exposing those bits even on Intel chips, for fine-grained control |
| of what's available. |
| |
| It is non-trivial to use x86_match_cpu() for this table because that |
| doesn't handle steppings. And the approach taken in commit bd9240a18 |
| almost made me lose my lunch. |
| |
| Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Cc: gnomes@lxorguk.ukuu.org.uk |
| Cc: ak@linux.intel.com |
| Cc: ashok.raj@intel.com |
| Cc: dave.hansen@intel.com |
| Cc: karahmed@amazon.de |
| Cc: arjan@linux.intel.com |
| Cc: torvalds@linux-foundation.org |
| Cc: peterz@infradead.org |
| Cc: bp@alien8.de |
| Cc: pbonzini@redhat.com |
| Cc: tim.c.chen@linux.intel.com |
| Cc: gregkh@linux-foundation.org |
| Link: https://lkml.kernel.org/r/1516896855-7642-7-git-send-email-dwmw@amazon.co.uk |
| Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/include/asm/intel-family.h | 7 ++- |
| arch/x86/kernel/cpu/intel.c | 66 ++++++++++++++++++++++++++++++++++++ |
| 2 files changed, 71 insertions(+), 2 deletions(-) |
| |
| --- a/arch/x86/include/asm/intel-family.h |
| +++ b/arch/x86/include/asm/intel-family.h |
| @@ -12,6 +12,7 @@ |
| */ |
| |
| #define INTEL_FAM6_CORE_YONAH 0x0E |
| + |
| #define INTEL_FAM6_CORE2_MEROM 0x0F |
| #define INTEL_FAM6_CORE2_MEROM_L 0x16 |
| #define INTEL_FAM6_CORE2_PENRYN 0x17 |
| @@ -21,6 +22,7 @@ |
| #define INTEL_FAM6_NEHALEM_G 0x1F /* Auburndale / Havendale */ |
| #define INTEL_FAM6_NEHALEM_EP 0x1A |
| #define INTEL_FAM6_NEHALEM_EX 0x2E |
| + |
| #define INTEL_FAM6_WESTMERE 0x25 |
| #define INTEL_FAM6_WESTMERE_EP 0x2C |
| #define INTEL_FAM6_WESTMERE_EX 0x2F |
| @@ -36,9 +38,9 @@ |
| #define INTEL_FAM6_HASWELL_GT3E 0x46 |
| |
| #define INTEL_FAM6_BROADWELL_CORE 0x3D |
| -#define INTEL_FAM6_BROADWELL_XEON_D 0x56 |
| #define INTEL_FAM6_BROADWELL_GT3E 0x47 |
| #define INTEL_FAM6_BROADWELL_X 0x4F |
| +#define INTEL_FAM6_BROADWELL_XEON_D 0x56 |
| |
| #define INTEL_FAM6_SKYLAKE_MOBILE 0x4E |
| #define INTEL_FAM6_SKYLAKE_DESKTOP 0x5E |
| @@ -57,9 +59,10 @@ |
| #define INTEL_FAM6_ATOM_SILVERMONT2 0x4D /* Avaton/Rangely */ |
| #define INTEL_FAM6_ATOM_AIRMONT 0x4C /* CherryTrail / Braswell */ |
| #define INTEL_FAM6_ATOM_MERRIFIELD 0x4A /* Tangier */ |
| -#define INTEL_FAM6_ATOM_MOOREFIELD 0x5A /* Annidale */ |
| +#define INTEL_FAM6_ATOM_MOOREFIELD 0x5A /* Anniedale */ |
| #define INTEL_FAM6_ATOM_GOLDMONT 0x5C |
| #define INTEL_FAM6_ATOM_DENVERTON 0x5F /* Goldmont Microserver */ |
| +#define INTEL_FAM6_ATOM_GEMINI_LAKE 0x7A |
| |
| /* Xeon Phi */ |
| |
| --- a/arch/x86/kernel/cpu/intel.c |
| +++ b/arch/x86/kernel/cpu/intel.c |
| @@ -61,6 +61,59 @@ void check_mpx_erratum(struct cpuinfo_x8 |
| } |
| } |
| |
| +/* |
| + * Early microcode releases for the Spectre v2 mitigation were broken. |
| + * Information taken from; |
| + * - https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/microcode-update-guidance.pdf |
| + * - https://kb.vmware.com/s/article/52345 |
| + * - Microcode revisions observed in the wild |
| + * - Release note from 20180108 microcode release |
| + */ |
| +struct sku_microcode { |
| + u8 model; |
| + u8 stepping; |
| + u32 microcode; |
| +}; |
| +static const struct sku_microcode spectre_bad_microcodes[] = { |
| + { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0B, 0x84 }, |
| + { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0A, 0x84 }, |
| + { INTEL_FAM6_KABYLAKE_DESKTOP, 0x09, 0x84 }, |
| + { INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x84 }, |
| + { INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x84 }, |
| + { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, |
| + { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, |
| + { INTEL_FAM6_SKYLAKE_MOBILE, 0x03, 0xc2 }, |
| + { INTEL_FAM6_SKYLAKE_DESKTOP, 0x03, 0xc2 }, |
| + { INTEL_FAM6_BROADWELL_CORE, 0x04, 0x28 }, |
| + { INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b }, |
| + { INTEL_FAM6_BROADWELL_XEON_D, 0x02, 0x14 }, |
| + { INTEL_FAM6_BROADWELL_XEON_D, 0x03, 0x07000011 }, |
| + { INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 }, |
| + { INTEL_FAM6_HASWELL_ULT, 0x01, 0x21 }, |
| + { INTEL_FAM6_HASWELL_GT3E, 0x01, 0x18 }, |
| + { INTEL_FAM6_HASWELL_CORE, 0x03, 0x23 }, |
| + { INTEL_FAM6_HASWELL_X, 0x02, 0x3b }, |
| + { INTEL_FAM6_HASWELL_X, 0x04, 0x10 }, |
| + { INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a }, |
| + /* Updated in the 20180108 release; blacklist until we know otherwise */ |
| + { INTEL_FAM6_ATOM_GEMINI_LAKE, 0x01, 0x22 }, |
| + /* Observed in the wild */ |
| + { INTEL_FAM6_SANDYBRIDGE_X, 0x06, 0x61b }, |
| + { INTEL_FAM6_SANDYBRIDGE_X, 0x07, 0x712 }, |
| +}; |
| + |
| +static bool bad_spectre_microcode(struct cpuinfo_x86 *c) |
| +{ |
| + int i; |
| + |
| + for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) { |
| + if (c->x86_model == spectre_bad_microcodes[i].model && |
| + c->x86_mask == spectre_bad_microcodes[i].stepping) |
| + return (c->microcode <= spectre_bad_microcodes[i].microcode); |
| + } |
| + return false; |
| +} |
| + |
| static void early_init_intel(struct cpuinfo_x86 *c) |
| { |
| u64 misc_enable; |
| @@ -87,6 +140,19 @@ static void early_init_intel(struct cpui |
| rdmsr(MSR_IA32_UCODE_REV, lower_word, c->microcode); |
| } |
| |
| + if ((cpu_has(c, X86_FEATURE_SPEC_CTRL) || |
| + cpu_has(c, X86_FEATURE_STIBP) || |
| + cpu_has(c, X86_FEATURE_AMD_SPEC_CTRL) || |
| + cpu_has(c, X86_FEATURE_AMD_PRED_CMD) || |
| + cpu_has(c, X86_FEATURE_AMD_STIBP)) && bad_spectre_microcode(c)) { |
| + pr_warn("Intel Spectre v2 broken microcode detected; disabling SPEC_CTRL\n"); |
| + clear_cpu_cap(c, X86_FEATURE_SPEC_CTRL); |
| + clear_cpu_cap(c, X86_FEATURE_STIBP); |
| + clear_cpu_cap(c, X86_FEATURE_AMD_SPEC_CTRL); |
| + clear_cpu_cap(c, X86_FEATURE_AMD_PRED_CMD); |
| + clear_cpu_cap(c, X86_FEATURE_AMD_STIBP); |
| + } |
| + |
| /* |
| * Atom erratum AAE44/AAF40/AAG38/AAH41: |
| * |