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 Index: linux/arch/i386/kernel/microcode.c =================================================================== --- linux.orig/arch/i386/kernel/microcode.c +++ linux/arch/i386/kernel/microcode.c @@ -165,7 +165,7 @@ static void collect_cpu_info (void *unus wrmsr(MSR_IA32_UCODE_REV, 0, 0); /* see notes above for revision 1.07. Apparent chip bug */ - serialize_cpu(); + sync_core(); /* get the current revision from MSR 0x8B */ rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev); pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", @@ -379,7 +379,7 @@ static void do_update_one (void * unused wrmsr(MSR_IA32_UCODE_REV, 0, 0); /* see notes above for revision 1.07. Apparent chip bug */ - serialize_cpu(); + sync_core(); /* get the current revision from MSR 0x8B */ rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); Index: linux/include/asm-i386/processor.h =================================================================== --- linux.orig/include/asm-i386/processor.h +++ linux/include/asm-i386/processor.h @@ -281,9 +281,11 @@ static inline void clear_in_cr4 (unsigne outb((data), 0x23); \ } while (0) -static inline void serialize_cpu(void) +/* Stop speculative execution */ +static inline void sync_core(void) { - __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + int tmp; + asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory"); } static inline void __monitor(const void *eax, unsigned long ecx,