https://git.reactos.org/?p=reactos.git;a=commitdiff;h=04906f2abbae83c2a475e…
commit 04906f2abbae83c2a475ea31555a2eb5b5a09960
Author:     Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue Apr 23 03:42:24 2019 +0200
Commit:     Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu Jun 20 19:39:44 2019 +0200
    [NTOS:KE] Fixup for the NMI task handler: handle NMI recursion. -- Code was lost in
commit 2efed8ef (r45040).
---
 ntoskrnl/include/internal/i386/asmmacro.S | 15 ++++++++++-----
 ntoskrnl/ke/i386/trap.s                   |  2 +-
 ntoskrnl/ke/i386/traphdlr.c               | 28 +++++++++++++---------------
 3 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/ntoskrnl/include/internal/i386/asmmacro.S
b/ntoskrnl/include/internal/i386/asmmacro.S
index 57f83b7ced..f7af217cc9 100644
--- a/ntoskrnl/include/internal/i386/asmmacro.S
+++ b/ntoskrnl/include/internal/i386/asmmacro.S
@@ -249,19 +249,24 @@ MACRO(TRAP_ENTRY, Trap, Flags)
     .ENDP
 ENDM
+#define KI_NMI  HEX(0001)
+
 MACRO(TASK_ENTRY, Trap, Flags)
-    // EXTERN @&Trap&Handler@0 :PROC
     EXTERN _&Trap&Handler :PROC
     PUBLIC _&Trap
     .PROC _&Trap
         /* Generate proper debugging symbols */
         FPO 0, 0, 0, 0, 0, FRAME_TSS
-        // /* Common code to create the trap frame */
-        // KiEnterTrap Flags
-
         /* Call the C handler */
-        KiCallHandler _&Trap&Handler // @&Trap&Handler@0
+        call _&Trap&Handler
+
+        if (Flags AND KI_NMI)
+            /* Return from NMI: return with iret and handle NMI recursion */
+            iretd
+            jmp _&Trap
+        endif
+
     .ENDP
 ENDM
diff --git a/ntoskrnl/ke/i386/trap.s b/ntoskrnl/ke/i386/trap.s
index d70ff66404..f3496f0ebc 100644
--- a/ntoskrnl/ke/i386/trap.s
+++ b/ntoskrnl/ke/i386/trap.s
@@ -97,7 +97,7 @@ ENDR
 TRAP_ENTRY KiTrap00, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap01, KI_PUSH_FAKE_ERROR_CODE
-TASK_ENTRY KiTrap02, 0
+TASK_ENTRY KiTrap02, KI_NMI
 TRAP_ENTRY KiTrap03, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap04, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap05, KI_PUSH_FAKE_ERROR_CODE
diff --git a/ntoskrnl/ke/i386/traphdlr.c b/ntoskrnl/ke/i386/traphdlr.c
index 863641bb68..e262bb85b9 100644
--- a/ntoskrnl/ke/i386/traphdlr.c
+++ b/ntoskrnl/ke/i386/traphdlr.c
@@ -455,7 +455,6 @@ KiTrap01Handler(IN PKTRAP_FRAME TrapFrame)
                              TrapFrame);
 }
-DECLSPEC_NORETURN
 VOID
 __cdecl
 KiTrap02Handler(VOID)
@@ -561,25 +560,24 @@ KiTrap02Handler(VOID)
      * We have to make sure we're still in our original NMI -- a nested NMI
      * will point back to the NMI TSS, and in that case we're hosed.
      */
-    if (PCR->TSS->Backlink != KGDT_NMI_TSS)
+    if (PCR->TSS->Backlink == KGDT_NMI_TSS)
     {
-        /* Restore original TSS */
-        PCR->TSS = Tss;
+        /* Unhandled: crash the system */
+        KiSystemFatalException(EXCEPTION_NMI, NULL);
+    }
-        /* Set it back to busy */
-        TssGdt->HighWord.Bits.Dpl = 0;
-        TssGdt->HighWord.Bits.Pres = 1;
-        TssGdt->HighWord.Bits.Type = I386_ACTIVE_TSS;
+    /* Restore original TSS */
+    PCR->TSS = Tss;
-        /* Restore nested flag */
-        __writeeflags(__readeflags() | EFLAGS_NESTED_TASK);
+    /* Set it back to busy */
+    TssGdt->HighWord.Bits.Dpl = 0;
+    TssGdt->HighWord.Bits.Pres = 1;
+    TssGdt->HighWord.Bits.Type = I386_ACTIVE_TSS;
-        /* Handled, return from interrupt */
-        KiIret();
-    }
+    /* Restore nested flag */
+    __writeeflags(__readeflags() | EFLAGS_NESTED_TASK);
-    /* Unhandled: crash the system */
-    KiSystemFatalException(EXCEPTION_NMI, NULL);
+    /* Handled, return from interrupt */
 }
 DECLSPEC_NORETURN