@@ -102,6 +102,59 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c)
102
102
ELF_HWCAP2 |= HWCAP2_RING3MWAIT ;
103
103
}
104
104
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
+
105
158
static void early_init_intel (struct cpuinfo_x86 * c )
106
159
{
107
160
u64 misc_enable ;
@@ -122,6 +175,19 @@ static void early_init_intel(struct cpuinfo_x86 *c)
122
175
if (c -> x86 >= 6 && !cpu_has (c , X86_FEATURE_IA64 ))
123
176
c -> microcode = intel_get_microcode_revision ();
124
177
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
+
125
191
/*
126
192
* Atom erratum AAE44/AAF40/AAG38/AAH41:
127
193
*
0 commit comments