aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/kernel/cpu/microcode/internal.h
diff options
context:
space:
mode:
authorThomas Gleixner <[email protected]>2023-10-02 14:00:05 +0200
committerBorislav Petkov (AMD) <[email protected]>2023-10-24 15:05:55 +0200
commit7eb314a22800457396f541c655697dabd71e44a7 (patch)
tree381820e5f0cf90a0bf7a88a6b9f908aede78b516 /arch/x86/kernel/cpu/microcode/internal.h
parent0bf871651211b58c7b19f40b746b646d5311e2ec (diff)
x86/microcode: Rendezvous and load in NMI
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: Thomas Gleixner <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/internal.h')
-rw-r--r--arch/x86/kernel/cpu/microcode/internal.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu/microcode/internal.h
index c6990431b5de..627d23809b89 100644
--- a/arch/x86/kernel/cpu/microcode/internal.h
+++ b/arch/x86/kernel/cpu/microcode/internal.h
@@ -31,7 +31,8 @@ struct microcode_ops {
enum ucode_state (*apply_microcode)(int cpu);
int (*collect_cpu_info)(int cpu, struct cpu_signature *csig);
void (*finalize_late_load)(int result);
- unsigned int nmi_safe : 1;
+ unsigned int nmi_safe : 1,
+ use_nmi : 1;
};
extern struct ucode_cpu_info ucode_cpu_info[];