Skip to content

Commit a5b2966

Browse files
dwmw2KAGA-KOKO
authored andcommitted
x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes
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 bd9240a almost made me lose my lunch. Signed-off-by: David Woodhouse <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent fec9434 commit a5b2966

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

arch/x86/kernel/cpu/intel.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,59 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c)
102102
ELF_HWCAP2 |= HWCAP2_RING3MWAIT;
103103
}
104104

105+
/*
106+
* Early microcode releases for the Spectre v2 mitigation were broken.
107+
* Information taken from;
108+
* - https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/microcode-update-guidance.pdf
109+
* - https://kb.vmware.com/s/article/52345
110+
* - Microcode revisions observed in the wild
111+
* - Release note from 20180108 microcode release
112+
*/
113+
struct sku_microcode {
114+
u8 model;
115+
u8 stepping;
116+
u32 microcode;
117+
};
118+
static const struct sku_microcode spectre_bad_microcodes[] = {
119+
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x0B, 0x84 },
120+
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x0A, 0x84 },
121+
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x09, 0x84 },
122+
{ INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x84 },
123+
{ INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x84 },
124+
{ INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e },
125+
{ INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c },
126+
{ INTEL_FAM6_SKYLAKE_MOBILE, 0x03, 0xc2 },
127+
{ INTEL_FAM6_SKYLAKE_DESKTOP, 0x03, 0xc2 },
128+
{ INTEL_FAM6_BROADWELL_CORE, 0x04, 0x28 },
129+
{ INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b },
130+
{ INTEL_FAM6_BROADWELL_XEON_D, 0x02, 0x14 },
131+
{ INTEL_FAM6_BROADWELL_XEON_D, 0x03, 0x07000011 },
132+
{ INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 },
133+
{ INTEL_FAM6_HASWELL_ULT, 0x01, 0x21 },
134+
{ INTEL_FAM6_HASWELL_GT3E, 0x01, 0x18 },
135+
{ INTEL_FAM6_HASWELL_CORE, 0x03, 0x23 },
136+
{ INTEL_FAM6_HASWELL_X, 0x02, 0x3b },
137+
{ INTEL_FAM6_HASWELL_X, 0x04, 0x10 },
138+
{ INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a },
139+
/* Updated in the 20180108 release; blacklist until we know otherwise */
140+
{ INTEL_FAM6_ATOM_GEMINI_LAKE, 0x01, 0x22 },
141+
/* Observed in the wild */
142+
{ INTEL_FAM6_SANDYBRIDGE_X, 0x06, 0x61b },
143+
{ INTEL_FAM6_SANDYBRIDGE_X, 0x07, 0x712 },
144+
};
145+
146+
static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
147+
{
148+
int i;
149+
150+
for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
151+
if (c->x86_model == spectre_bad_microcodes[i].model &&
152+
c->x86_mask == spectre_bad_microcodes[i].stepping)
153+
return (c->microcode <= spectre_bad_microcodes[i].microcode);
154+
}
155+
return false;
156+
}
157+
105158
static void early_init_intel(struct cpuinfo_x86 *c)
106159
{
107160
u64 misc_enable;
@@ -122,6 +175,19 @@ static void early_init_intel(struct cpuinfo_x86 *c)
122175
if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64))
123176
c->microcode = intel_get_microcode_revision();
124177

178+
if ((cpu_has(c, X86_FEATURE_SPEC_CTRL) ||
179+
cpu_has(c, X86_FEATURE_STIBP) ||
180+
cpu_has(c, X86_FEATURE_AMD_SPEC_CTRL) ||
181+
cpu_has(c, X86_FEATURE_AMD_PRED_CMD) ||
182+
cpu_has(c, X86_FEATURE_AMD_STIBP)) && bad_spectre_microcode(c)) {
183+
pr_warn("Intel Spectre v2 broken microcode detected; disabling SPEC_CTRL\n");
184+
clear_cpu_cap(c, X86_FEATURE_SPEC_CTRL);
185+
clear_cpu_cap(c, X86_FEATURE_STIBP);
186+
clear_cpu_cap(c, X86_FEATURE_AMD_SPEC_CTRL);
187+
clear_cpu_cap(c, X86_FEATURE_AMD_PRED_CMD);
188+
clear_cpu_cap(c, X86_FEATURE_AMD_STIBP);
189+
}
190+
125191
/*
126192
* Atom erratum AAE44/AAF40/AAG38/AAH41:
127193
*

0 commit comments

Comments
 (0)