diff options
Diffstat (limited to 'arch/x86/kernel/cpu/intel.c')
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index b1af22073e28..319bf989fad1 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -102,6 +102,59 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c) | |||
102 | ELF_HWCAP2 |= HWCAP2_RING3MWAIT; | 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 | static void early_init_intel(struct cpuinfo_x86 *c) | 158 | static void early_init_intel(struct cpuinfo_x86 *c) |
106 | { | 159 | { |
107 | u64 misc_enable; | 160 | u64 misc_enable; |
@@ -122,6 +175,19 @@ static void early_init_intel(struct cpuinfo_x86 *c) | |||
122 | if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64)) | 175 | if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64)) |
123 | c->microcode = intel_get_microcode_revision(); | 176 | c->microcode = intel_get_microcode_revision(); |
124 | 177 | ||
178 | /* Now if any of them are set, check the blacklist and clear the lot */ | ||
179 | if ((cpu_has(c, X86_FEATURE_SPEC_CTRL) || | ||
180 | cpu_has(c, X86_FEATURE_INTEL_STIBP) || | ||
181 | cpu_has(c, X86_FEATURE_IBRS) || cpu_has(c, X86_FEATURE_IBPB) || | ||
182 | cpu_has(c, X86_FEATURE_STIBP)) && bad_spectre_microcode(c)) { | ||
183 | pr_warn("Intel Spectre v2 broken microcode detected; disabling Speculation Control\n"); | ||
184 | setup_clear_cpu_cap(X86_FEATURE_IBRS); | ||
185 | setup_clear_cpu_cap(X86_FEATURE_IBPB); | ||
186 | setup_clear_cpu_cap(X86_FEATURE_STIBP); | ||
187 | setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL); | ||
188 | setup_clear_cpu_cap(X86_FEATURE_INTEL_STIBP); | ||
189 | } | ||
190 | |||
125 | /* | 191 | /* |
126 | * Atom erratum AAE44/AAF40/AAG38/AAH41: | 192 | * Atom erratum AAE44/AAF40/AAG38/AAH41: |
127 | * | 193 | * |