Commit 487472bc01fab0625996aad37836aad931e4eda9
Committed by
Linus Torvalds
1 parent
c818a18146
Exists in
master
and in
4 other branches
[PATCH] i386: Replace broken serialize_cpu in microcode driver with correct sync_core
Passing random input values in eax to cpuid is not a good idea because the CPU will GPF for unknown ones. Use the correct x86-64 version that exists for a longer time too. This also adds a memory barrier to prevent the optimizer from reordering. Cc: tigran@veritas.com Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 2 changed files with 6 additions and 4 deletions Side-by-side Diff
arch/i386/kernel/microcode.c
| ... | ... | @@ -166,7 +166,7 @@ |
| 166 | 166 | |
| 167 | 167 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); |
| 168 | 168 | /* see notes above for revision 1.07. Apparent chip bug */ |
| 169 | - serialize_cpu(); | |
| 169 | + sync_core(); | |
| 170 | 170 | /* get the current revision from MSR 0x8B */ |
| 171 | 171 | rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev); |
| 172 | 172 | pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", |
| ... | ... | @@ -380,7 +380,7 @@ |
| 380 | 380 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); |
| 381 | 381 | |
| 382 | 382 | /* see notes above for revision 1.07. Apparent chip bug */ |
| 383 | - serialize_cpu(); | |
| 383 | + sync_core(); | |
| 384 | 384 | |
| 385 | 385 | /* get the current revision from MSR 0x8B */ |
| 386 | 386 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); |
include/asm-i386/processor.h
| ... | ... | @@ -281,9 +281,11 @@ |
| 281 | 281 | outb((data), 0x23); \ |
| 282 | 282 | } while (0) |
| 283 | 283 | |
| 284 | -static inline void serialize_cpu(void) | |
| 284 | +/* Stop speculative execution */ | |
| 285 | +static inline void sync_core(void) | |
| 285 | 286 | { |
| 286 | - __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); | |
| 287 | + int tmp; | |
| 288 | + asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory"); | |
| 287 | 289 | } |
| 288 | 290 | |
| 289 | 291 | static inline void __monitor(const void *eax, unsigned long ecx, |