From 121db039368608b38a669dfd0f28ce0390a5905e Mon Sep 17 00:00:00 2001 From: Joachim Henze Date: Sun, 3 Nov 2019 17:36:40 +0100 Subject: [PATCH] [0.4.13] Revert 3 [NTOS:KE] commits to avoid regression CORE-16448 Symptom: stacklog via 'bt' command in gcc+kdbg regressed in certain cases. This reverts the guilty commit 0.4.13-dev-514-g 3c8f19eb2153034b9b47fc91284b54b1200f21d8. But also reverts 2 tightly related follow-up commits 0.4.13-dev-515-g 04906f2abbae83c2a475ea31555a2eb5b5a09960 and 0.4.13-dev-516-g 4d5a2dd0f3c39921ba20c1cb9a5c208bea94e5fe We revert only in RC, but master remains affected for now, the developers aim to fix master by WIP PR#2003 later. I considered following the bleeding-edge-development being too risky here. Many unrelated changes in master since then. --- ntoskrnl/include/internal/i386/asmmacro.S | 21 ----- ntoskrnl/include/internal/i386/ke.h | 2 +- ntoskrnl/ke/i386/trap.s | 5 +- ntoskrnl/ke/i386/traphdlr.c | 98 +++++++---------------- 4 files changed, 33 insertions(+), 93 deletions(-) diff --git a/ntoskrnl/include/internal/i386/asmmacro.S b/ntoskrnl/include/internal/i386/asmmacro.S index f7af217cc9f..6d2d213c3d6 100644 --- a/ntoskrnl/include/internal/i386/asmmacro.S +++ b/ntoskrnl/include/internal/i386/asmmacro.S @@ -249,27 +249,6 @@ MACRO(TRAP_ENTRY, Trap, Flags) .ENDP ENDM -#define KI_NMI HEX(0001) - -MACRO(TASK_ENTRY, Trap, Flags) - EXTERN _&Trap&Handler :PROC - PUBLIC _&Trap - .PROC _&Trap - /* Generate proper debugging symbols */ - FPO 0, 0, 0, 0, 0, FRAME_TSS - - /* Call the C handler */ - call _&Trap&Handler - - if (Flags AND KI_NMI) - /* Return from NMI: return with iret and handle NMI recursion */ - iretd - jmp _&Trap - endif - - .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 7ce491e2915..10eb6eb1bed 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 VOID __cdecl KiTrap02(VOID); +extern DECLSPEC_NORETURN 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 f3496f0ebc3..6bd57e80532 100644 --- a/ntoskrnl/ke/i386/trap.s +++ b/ntoskrnl/ke/i386/trap.s @@ -27,6 +27,8 @@ _KiUnexpectedInterrupt&Vector: //.endfunc ENDM +EXTERN _KiTrap02:PROC + /* GLOBALS *******************************************************************/ .data @@ -97,13 +99,12 @@ ENDR TRAP_ENTRY KiTrap00, KI_PUSH_FAKE_ERROR_CODE TRAP_ENTRY KiTrap01, KI_PUSH_FAKE_ERROR_CODE -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 TRAP_ENTRY KiTrap06, KI_PUSH_FAKE_ERROR_CODE TRAP_ENTRY KiTrap07, KI_PUSH_FAKE_ERROR_CODE -TASK_ENTRY KiTrap08, 0 +TRAP_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 6f26ac99a78..7cf1fcde37e 100644 --- a/ntoskrnl/ke/i386/traphdlr.c +++ b/ntoskrnl/ke/i386/traphdlr.c @@ -455,9 +455,10 @@ KiTrap01Handler(IN PKTRAP_FRAME TrapFrame) TrapFrame); } +DECLSPEC_NORETURN VOID __cdecl -KiTrap02Handler(VOID) +KiTrap02(VOID) { PKTSS Tss, NmiTss; PKTHREAD Thread; @@ -477,8 +478,8 @@ KiTrap02Handler(VOID) _disable(); /* Get the current TSS, thread, and process */ - Tss = KeGetPcr()->TSS; - Thread = ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread; + Tss = PCR->TSS; + Thread = ((PKIPCR)PCR)->PrcbData.CurrentThread; Process = Thread->ApcState.Process; /* Save data usually not present in the TSS */ @@ -498,7 +499,7 @@ KiTrap02Handler(VOID) * Note that in reality, we are already on the NMI TSS -- we just * need to update the PCR to reflect this. */ - KeGetPcr()->TSS = NmiTss; + PCR->TSS = NmiTss; __writeeflags(__readeflags() &~ EFLAGS_NESTED_TASK); TssGdt->HighWord.Bits.Dpl = 0; TssGdt->HighWord.Bits.Pres = 1; @@ -523,7 +524,7 @@ KiTrap02Handler(VOID) TrapFrame.Esi = Tss->Esi; TrapFrame.Edi = Tss->Edi; TrapFrame.SegFs = Tss->Fs; - TrapFrame.ExceptionList = KeGetPcr()->NtTib.ExceptionList; + TrapFrame.ExceptionList = PCR->NtTib.ExceptionList; TrapFrame.PreviousPreviousMode = (ULONG)-1; TrapFrame.Eax = Tss->Eax; TrapFrame.Ecx = Tss->Ecx; @@ -547,10 +548,10 @@ KiTrap02Handler(VOID) * the normal APIs here as playing with the IRQL could change the system * state. */ - OldIrql = KeGetPcr()->Irql; - KeGetPcr()->Irql = HIGH_LEVEL; + OldIrql = PCR->Irql; + PCR->Irql = HIGH_LEVEL; HalHandleNMI(NULL); - KeGetPcr()->Irql = OldIrql; + PCR->Irql = OldIrql; } /* @@ -560,24 +561,25 @@ 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 (KeGetPcr()->TSS->Backlink == KGDT_NMI_TSS) + if (PCR->TSS->Backlink != KGDT_NMI_TSS) { - /* Unhandled: crash the system */ - KiSystemFatalException(EXCEPTION_NMI, NULL); + /* Restore original TSS */ + PCR->TSS = Tss; + + /* Set it back to busy */ + TssGdt->HighWord.Bits.Dpl = 0; + TssGdt->HighWord.Bits.Pres = 1; + TssGdt->HighWord.Bits.Type = I386_ACTIVE_TSS; + + /* Restore nested flag */ + __writeeflags(__readeflags() | EFLAGS_NESTED_TASK); + + /* Handled, return from interrupt */ + KiIret(); } - /* Restore original TSS */ - KeGetPcr()->TSS = Tss; - - /* Set it back to busy */ - TssGdt->HighWord.Bits.Dpl = 0; - TssGdt->HighWord.Bits.Pres = 1; - TssGdt->HighWord.Bits.Type = I386_ACTIVE_TSS; - - /* Restore nested flag */ - __writeeflags(__readeflags() | EFLAGS_NESTED_TASK); - - /* Handled, return from interrupt */ + /* Unhandled: crash the system */ + KiSystemFatalException(EXCEPTION_NMI, NULL); } DECLSPEC_NORETURN @@ -827,53 +829,11 @@ KiTrap07Handler(IN PKTRAP_FRAME TrapFrame) DECLSPEC_NORETURN VOID -__cdecl -KiTrap08Handler(VOID) +FASTCALL +KiTrap08Handler(IN PKTRAP_FRAME 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); + /* FIXME: Not handled */ + KiSystemFatalException(EXCEPTION_DOUBLE_FAULT, TrapFrame); } DECLSPEC_NORETURN