https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3c8f19eb2153034b9b47fc91284b54b1200f21d8

commit 3c8f19eb2153034b9b47fc91284b54b1200f21d8
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Mon Feb 4 01:16:29 2019 +0100
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Thu Jun 20 19:38:56 2019 +0200

    [NTOS:KE] Improvements for the Trap02 (NMI) and Trap08 (double-fault) 
exception handlers.
    
    - Add FRAME_TSS FPO debug information for Trap02 and Trap08.
    - Switch the active TSS in Trap08 in the very same way as is done in Trap02.
    
    This allows to correctly debug NMI and double-fault exceptions with WinDbg,
    by following the different TSS contexts, as described in:
    
https://blogs.msdn.microsoft.com/debuggingtoolbox/2008/02/22/special-command-analyzing-and-reconstructing-the-stack-using-the-k-command-and-its-variations/
    
https://blogs.msdn.microsoft.com/ntdebugging/2009/11/25/part-1-got-stack-no-we-ran-out-of-kernel-mode-stack-and-kv-wont-tell-me-why/
    http://www.osronline.com/article.cfm?article=254 and 
http://www.osronline.com/article.cfm?article=328
---
 ntoskrnl/include/internal/i386/asmmacro.S | 16 ++++++++++
 ntoskrnl/include/internal/i386/ke.h       |  2 +-
 ntoskrnl/ke/i386/trap.s                   |  5 ++-
 ntoskrnl/ke/i386/traphdlr.c               | 52 ++++++++++++++++++++++++++++---
 4 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/ntoskrnl/include/internal/i386/asmmacro.S 
b/ntoskrnl/include/internal/i386/asmmacro.S
index 6d2d213c3d..57f83b7ced 100644
--- a/ntoskrnl/include/internal/i386/asmmacro.S
+++ b/ntoskrnl/include/internal/i386/asmmacro.S
@@ -249,6 +249,22 @@ MACRO(TRAP_ENTRY, Trap, Flags)
     .ENDP
 ENDM
 
+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
+    .ENDP
+ENDM
+
 #define KI_RESTORE_EAX        HEX(0001)
 #define KI_RESTORE_ECX_EDX    HEX(0002)
 #define KI_RESTORE_FS         HEX(0004)
diff --git a/ntoskrnl/include/internal/i386/ke.h 
b/ntoskrnl/include/internal/i386/ke.h
index 10eb6eb1be..7ce491e291 100644
--- a/ntoskrnl/include/internal/i386/ke.h
+++ b/ntoskrnl/include/internal/i386/ke.h
@@ -575,7 +575,7 @@ extern ULONG KeI386CpuStep;
 extern ULONG KiFastSystemCallDisable;
 extern UCHAR KiDebugRegisterTrapOffsets[9];
 extern UCHAR KiDebugRegisterContextOffsets[9];
-extern DECLSPEC_NORETURN VOID __cdecl KiTrap02(VOID);
+extern VOID __cdecl KiTrap02(VOID);
 extern VOID __cdecl KiTrap08(VOID);
 extern VOID __cdecl KiTrap13(VOID);
 extern VOID __cdecl KiFastCallEntry(VOID);
diff --git a/ntoskrnl/ke/i386/trap.s b/ntoskrnl/ke/i386/trap.s
index 6bd57e8053..d70ff66404 100644
--- a/ntoskrnl/ke/i386/trap.s
+++ b/ntoskrnl/ke/i386/trap.s
@@ -27,8 +27,6 @@ _KiUnexpectedInterrupt&Vector:
 //.endfunc
 ENDM
 
-EXTERN _KiTrap02:PROC
-
 /* GLOBALS *******************************************************************/
 
 .data
@@ -99,12 +97,13 @@ ENDR
 
 TRAP_ENTRY KiTrap00, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap01, KI_PUSH_FAKE_ERROR_CODE
+TASK_ENTRY KiTrap02, 0
 TRAP_ENTRY KiTrap03, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap04, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap05, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap06, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap07, KI_PUSH_FAKE_ERROR_CODE
-TRAP_ENTRY KiTrap08, 0
+TASK_ENTRY KiTrap08, 0
 TRAP_ENTRY KiTrap09, KI_PUSH_FAKE_ERROR_CODE
 TRAP_ENTRY KiTrap0A, 0
 TRAP_ENTRY KiTrap0B, 0
diff --git a/ntoskrnl/ke/i386/traphdlr.c b/ntoskrnl/ke/i386/traphdlr.c
index 7cf1fcde37..863641bb68 100644
--- a/ntoskrnl/ke/i386/traphdlr.c
+++ b/ntoskrnl/ke/i386/traphdlr.c
@@ -458,7 +458,7 @@ KiTrap01Handler(IN PKTRAP_FRAME TrapFrame)
 DECLSPEC_NORETURN
 VOID
 __cdecl
-KiTrap02(VOID)
+KiTrap02Handler(VOID)
 {
     PKTSS Tss, NmiTss;
     PKTHREAD Thread;
@@ -829,11 +829,53 @@ KiTrap07Handler(IN PKTRAP_FRAME TrapFrame)
 
 DECLSPEC_NORETURN
 VOID
-FASTCALL
-KiTrap08Handler(IN PKTRAP_FRAME TrapFrame)
+__cdecl
+KiTrap08Handler(VOID)
 {
-    /* FIXME: Not handled */
-    KiSystemFatalException(EXCEPTION_DOUBLE_FAULT, TrapFrame);
+    PKTSS Tss, DfTss;
+    PKTHREAD Thread;
+    PKPROCESS Process;
+    PKGDTENTRY TssGdt;
+
+    /* For sanity's sake, make sure interrupts are disabled */
+    _disable();
+
+    /* Get the current TSS, thread, and process */
+    Tss = KeGetPcr()->TSS;
+    Thread = ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread;
+    Process = Thread->ApcState.Process;
+
+    /* Save data usually not present in the TSS */
+    Tss->CR3 = Process->DirectoryTableBase[0];
+    Tss->IoMapBase = Process->IopmOffset;
+    Tss->LDT = Process->LdtDescriptor.LimitLow ? KGDT_LDT : 0;
+
+    /* Now get the base address of the double-fault TSS */
+    TssGdt = &((PKIPCR)KeGetPcr())->GDT[KGDT_DF_TSS / sizeof(KGDTENTRY)];
+    DfTss  = (PKTSS)(ULONG_PTR)(TssGdt->BaseLow |
+                                TssGdt->HighWord.Bytes.BaseMid << 16 |
+                                TssGdt->HighWord.Bytes.BaseHi << 24);
+
+    /*
+     * Switch to it and activate it, masking off the nested flag.
+     *
+     * Note that in reality, we are already on the double-fault TSS
+     * -- we just need to update the PCR to reflect this.
+     */
+    KeGetPcr()->TSS = DfTss;
+    __writeeflags(__readeflags() &~ EFLAGS_NESTED_TASK);
+    TssGdt->HighWord.Bits.Dpl = 0;
+    TssGdt->HighWord.Bits.Pres = 1;
+    // TssGdt->HighWord.Bits.Type &= ~0x2; /* I386_ACTIVE_TSS --> I386_TSS */
+    TssGdt->HighWord.Bits.Type = I386_TSS; // Busy bit cleared in the TSS 
selector.
+
+    /* Bugcheck the system */
+    KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
+                     EXCEPTION_DOUBLE_FAULT,
+                     (ULONG_PTR)Tss,
+                     0,
+                     0,
+                     NULL);
 }
 
 DECLSPEC_NORETURN

Reply via email to