TrapFrame);
}
-DECLSPEC_NORETURN
VOID
__cdecl
-KiTrap02(VOID)
+KiTrap02Handler(VOID)
{
PKTSS Tss, NmiTss;
PKTHREAD Thread;
_disable();
/* Get the current TSS, thread, and process */
- Tss = PCR->TSS;
- Thread = ((PKIPCR)PCR)->PrcbData.CurrentThread;
+ Tss = KeGetPcr()->TSS;
+ Thread = ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread;
Process = Thread->ApcState.Process;
/* Save data usually not present in the TSS */
* Note that in reality, we are already on the NMI TSS -- we just
* need to update the PCR to reflect this.
*/
- PCR->TSS = NmiTss;
+ KeGetPcr()->TSS = NmiTss;
__writeeflags(__readeflags() &~ EFLAGS_NESTED_TASK);
TssGdt->HighWord.Bits.Dpl = 0;
TssGdt->HighWord.Bits.Pres = 1;
TrapFrame.Esi = Tss->Esi;
TrapFrame.Edi = Tss->Edi;
TrapFrame.SegFs = Tss->Fs;
- TrapFrame.ExceptionList = PCR->NtTib.ExceptionList;
+ TrapFrame.ExceptionList = KeGetPcr()->NtTib.ExceptionList;
TrapFrame.PreviousPreviousMode = (ULONG)-1;
TrapFrame.Eax = Tss->Eax;
TrapFrame.Ecx = Tss->Ecx;
* the normal APIs here as playing with the IRQL could change the system
* state.
*/
- OldIrql = PCR->Irql;
- PCR->Irql = HIGH_LEVEL;
+ OldIrql = KeGetPcr()->Irql;
+ KeGetPcr()->Irql = HIGH_LEVEL;
HalHandleNMI(NULL);
- PCR->Irql = OldIrql;
+ KeGetPcr()->Irql = OldIrql;
}
/*
* 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 (KeGetPcr()->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 */
+ KeGetPcr()->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
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