Merge tag 'x86_seves_for_v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / arch / x86 / kernel / nmi.c
index 4738166..4bc77aa 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/reboot.h>
 #include <asm/cache.h>
 #include <asm/nospec-branch.h>
+#include <asm/sev-es.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/nmi.h>
@@ -476,6 +477,12 @@ DEFINE_IDTENTRY_RAW(exc_nmi)
 {
        bool irq_state;
 
+       /*
+        * Re-enable NMIs right here when running as an SEV-ES guest. This might
+        * cause nested NMIs, but those can be handled safely.
+        */
+       sev_es_nmi_complete();
+
        if (IS_ENABLED(CONFIG_SMP) && arch_cpu_is_offline(smp_processor_id()))
                return;
 
@@ -487,6 +494,12 @@ DEFINE_IDTENTRY_RAW(exc_nmi)
        this_cpu_write(nmi_cr2, read_cr2());
 nmi_restart:
 
+       /*
+        * Needs to happen before DR7 is accessed, because the hypervisor can
+        * intercept DR7 reads/writes, turning those into #VC exceptions.
+        */
+       sev_es_ist_enter(regs);
+
        this_cpu_write(nmi_dr7, local_db_save());
 
        irq_state = idtentry_enter_nmi(regs);
@@ -500,6 +513,8 @@ nmi_restart:
 
        local_db_restore(this_cpu_read(nmi_dr7));
 
+       sev_es_ist_exit();
+
        if (unlikely(this_cpu_read(nmi_cr2) != read_cr2()))
                write_cr2(this_cpu_read(nmi_cr2));
        if (this_cpu_dec_return(nmi_state))