• Thomas Gleixner's avatar
    x86/microcode: Rendezvous and load in NMI · 7eb314a2
    Thomas Gleixner authored
    stop_machine() does not prevent the spin-waiting sibling from handling
    an NMI, which is obviously violating the whole concept of rendezvous.
    
    Implement a static branch right in the beginning of the NMI handler
    which is nopped out except when enabled by the late loading mechanism.
    
    The late loader enables the static branch before stop_machine() is
    invoked. Each CPU has an nmi_enable in its control structure which
    indicates whether the CPU should go into the update routine.
    
    This is required to bridge the gap between enabling the branch and
    actually being at the point where it is required to enter the loader
    wait loop.
    
    Each CPU which arrives in the stopper thread function sets that flag and
    issues a self NMI right after that. If the NMI function sees the flag
    clear, it returns. If it's set it clears the flag and enters the
    rendezvous.
    
    This is safe against a real NMI which hits in between setting the flag
    and sending the NMI to itself. The real NMI will be swallowed by the
    microcode update and the self NMI will then let stuff continue.
    Otherwise this would end up with a spurious NMI.
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
    Link: https://lore.kernel.org/r/20231002115903.489900814@linutronix.de
    7eb314a2
intel.c 16.2 KB