• Borislav Petkov's avatar
    x86/microcode: Fix CPU synchronization routine · bb8c13d6
    Borislav Petkov authored
    Emanuel reported an issue with a hang during microcode update because my
    dumb idea to use one atomic synchronization variable for both rendezvous
    - before and after update - was simply bollocks:
    
      microcode: microcode_reload_late: late_cpus: 4
      microcode: __reload_late: cpu 2 entered
      microcode: __reload_late: cpu 1 entered
      microcode: __reload_late: cpu 3 entered
      microcode: __reload_late: cpu 0 entered
      microcode: __reload_late: cpu 1 left
      microcode: Timeout while waiting for CPUs rendezvous, remaining: 1
    
    CPU1 above would finish, leave and the others will still spin waiting for
    it to join.
    
    So do two synchronization atomics instead, which makes the code a lot more
    straightforward.
    
    Also, since the update is serialized and it also takes quite some time per
    microcode engine, increase the exit timeout by the number of CPUs on the
    system.
    
    That's ok because the moment all CPUs are done, that timeout will be cut
    short.
    
    Furthermore, panic when some of the CPUs timeout when returning from a
    microcode update: we can't allow a system with not all cores updated.
    
    Also, as an optimization, do not do the exit sync if microcode wasn't
    updated.
    Reported-by: default avatarEmanuel Czirai <xftroxgpx@protonmail.com>
    Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Tested-by: default avatarEmanuel Czirai <xftroxgpx@protonmail.com>
    Tested-by: default avatarAshok Raj <ashok.raj@intel.com>
    Tested-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
    Link: https://lkml.kernel.org/r/20180314183615.17629-2-bp@alien8.de
    bb8c13d6
core.c 18.9 KB