Author: ion Date: Mon Mar 19 06:29:29 2007 New Revision: 26137
URL: http://svn.reactos.org/svn/reactos?rev=26137&view=rev Log: - New ISR Timeout detection code. - New Interrupt Storm detection code. - Use PCR everywhere instead of fs:[ or [fs:. Significant improvements on UP builds because we use ds:[KPCRADDRESSS] for them. - Ongoing work.
Modified: trunk/reactos/include/ndk/asm.h trunk/reactos/include/ndk/ketypes.h trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S trunk/reactos/ntoskrnl/ke/i386/irqobj.c trunk/reactos/ntoskrnl/ke/i386/trap.s
Modified: trunk/reactos/include/ndk/asm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=26137... ============================================================================== --- trunk/reactos/include/ndk/asm.h (original) +++ trunk/reactos/include/ndk/asm.h Mon Mar 19 06:29:29 2007 @@ -222,10 +222,12 @@ // #define KINTERRUPT_SERVICE_ROUTINE 0x0C #define KINTERRUPT_SERVICE_CONTEXT 0x10 +#define KINTERRUPT_TICK_COUNT 0x18 #define KINTERRUPT_ACTUAL_LOCK 0x1C #define KINTERRUPT_IRQL 0x20 #define KINTERRUPT_VECTOR 0x24 #define KINTERRUPT_SYNCHRONIZE_IRQL 0x29 +#define KINTERRUPT_DISPATCH_COUNT 0x38
// // KGDTENTRY Offsets @@ -546,6 +548,7 @@ #define IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A #define UNEXPECTED_KERNEL_MODE_TRAP 0x7F #define ATTEMPTED_SWITCH_FROM_DPC 0xB8 +#define HARDWARE_INTERRUPT_STORM 0xF2
// // IRQL Levels @@ -607,3 +610,4 @@ #define MAXIMUM_IDTVECTOR 0xFF #endif // !_ASM_H
+
Modified: trunk/reactos/include/ndk/ketypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/ketypes.h?rev=2... ============================================================================== --- trunk/reactos/include/ndk/ketypes.h (original) +++ trunk/reactos/include/ndk/ketypes.h Mon Mar 19 06:29:29 2007 @@ -622,14 +622,14 @@ KSPIN_LOCK SpinLock; ULONG TickCount; PKSPIN_LOCK ActualLock; - PVOID DispatchAddress; + PKINTERRUPT_ROUTINE DispatchAddress; ULONG Vector; KIRQL Irql; KIRQL SynchronizeIrql; BOOLEAN FloatingSave; BOOLEAN Connected; - CHAR Number; - UCHAR ShareVector; + CCHAR Number; + BOOLEAN ShareVector; KINTERRUPT_MODE Mode; #if (NTDDI_VERSION >= NTDDI_LONGHORN) KINTERRUPT_POLARITY Polarity;
Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S (original) +++ trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S Mon Mar 19 06:29:29 2007 @@ -353,7 +353,7 @@
/* Get the current thread */ 1: - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD]
/* Make it non-alerted */ mov byte ptr [ebx+KTHREAD_ALERTED], 0 @@ -440,7 +440,7 @@ mov fs, bx
/* Save exception list and bogus previous mode */ - push fs:[KPCR_EXCEPTION_LIST] + push PCR[KPCR_EXCEPTION_LIST] push -1
/* Save volatiles and segment registers */ @@ -476,7 +476,7 @@
1: /* Get current thread */ - mov ecx, [fs:KPCR_CURRENT_THREAD] + mov ecx, PCR[KPCR_CURRENT_THREAD] cld
/* Flush DR7 */ @@ -555,10 +555,10 @@
1: /* Get the previous exception list */ - mov ebx, [fs:KPCR_EXCEPTION_LIST] + mov ebx, PCR[KPCR_EXCEPTION_LIST]
/* Set the exception handler chain terminator */ - mov dword ptr [fs:KPCR_EXCEPTION_LIST], -1 + mov dword ptr PCR[KPCR_EXCEPTION_LIST], -1
/* Save the previous exception list */ mov [esp+KTRAP_FRAME_EXCEPTION_LIST], ebx @@ -579,7 +579,7 @@ and dword ptr [esp+KTRAP_FRAME_ERROR_CODE], 0
/* Get the current thread and clear direction flag */ - mov ecx, [fs:KPCR_CURRENT_THREAD] + mov ecx, PCR[KPCR_CURRENT_THREAD] cld
/* Flush DR7 */ @@ -631,13 +631,13 @@ mov fs, bx
/* Get a pointer to the current thread */ - mov esi, [fs:KPCR_CURRENT_THREAD] + mov esi, PCR[KPCR_CURRENT_THREAD]
/* Save the previous exception list */ - push [fs:KPCR_EXCEPTION_LIST] + push PCR[KPCR_EXCEPTION_LIST]
/* Set the exception handler chain terminator */ - mov dword ptr [fs:KPCR_EXCEPTION_LIST], -1 + mov dword ptr PCR[KPCR_EXCEPTION_LIST], -1
/* Save the old previous mode */ push [esi+KTHREAD_PREVIOUS_MODE] @@ -705,7 +705,7 @@ mov es, cx
/* Set the current stack to Kernel Stack */ - mov ecx, [fs:KPCR_TSS] + mov ecx, PCR[KPCR_TSS] mov esp, [ecx+KTSS_ESP0]
/* Set up a fake INT Stack. */ @@ -728,7 +728,7 @@ push KGDT_R3_TEB + RPL_MASK
/* Save pointer to our PCR */ - mov ebx, [fs:KPCR_SELF] + mov ebx, PCR[KPCR_SELF]
/* Get a pointer to the current thread */ mov esi, [ebx+KPCR_CURRENT_THREAD] @@ -831,7 +831,7 @@ cld
/* Save the exception list */ - mov eax, [fs:KPCR_EXCEPTION_LIST] + mov eax, PCR[KPCR_EXCEPTION_LIST] mov [esp+KTRAP_FRAME_EXCEPTION_LIST], eax
/* Check if we need debugging */ @@ -854,7 +854,7 @@
/* Get the current thread and make it unalerted */ ExitBegin: - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov byte ptr [ebx+KTHREAD_ALERTED], 0
/* Check if it has User-mode APCs pending */ @@ -954,7 +954,7 @@ jnz 1f
/* Assert exception list */ - cmp dword ptr fs:[KPCR_EXCEPTION_LIST], 0 + cmp dword ptr PCR[KPCR_EXCEPTION_LIST], 0 jnz 2f
1: @@ -975,7 +975,7 @@ #endif
/* Restore it */ - mov [fs:KPCR_EXCEPTION_LIST], edx + mov PCR[KPCR_EXCEPTION_LIST], edx
.if \RestorePreviousMode /* Get previous mode */ @@ -990,7 +990,7 @@ #endif
/* Restore the previous mode */ - mov esi, [fs:KPCR_CURRENT_THREAD] + mov esi, PCR[KPCR_CURRENT_THREAD] mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], cl .else
@@ -1211,3 +1211,117 @@ iret .endm
+// +// @name INT_EPILOG +// +// This macro creates an epilogue for leaving any system trap. +// It is used for exiting system calls, exceptions, interrupts and generic +// traps. +// +// @param Spurious - TRUE if the interrupt was unexpected and spurious. +// +// @remark None. +// +.macro INT_EPILOG Spurious + +.if \Spurious + /* Just exit the trap */ + jmp _Kei386EoiHelper@0 +.else + /* Disable interrupts */ + cli + + /* End the interrupt and do EOI */ + call _HalEndSystemInterrupt@8 + jmp _Kei386EoiHelper@0 +.endif +.endm + +#ifdef DBG + +.macro VERIFY_INT Label + /* Get the current time and mask it to 192 ticks */ + mov eax, _KeTickCount + and eax, 0xC0 + + /* Check if we're in the same tick area */ + cmp eax, dword ptr [edi+KINTERRUPT_TICK_COUNT] + jg VfRst_&Label + jl VfWrap_&Label + + /* If we got here, then our count is too large */ + dec word ptr [edi+KINTERRUPT_DISPATCH_COUNT] + jz VfOvr_&Label +Vf_&Label: +.endm + +.macro VERIFY_INT_END Label, Info +VfOvr_&Label: + + /* Decrement the dispatch count and check if we should bug check */ + dec word ptr [edi+KINTERRUPT_DISPATCH_COUNT+2] + jz 1f + + /* Update the tick count */ + add eax, 0x40 + mov [edi+KINTERRUPT_TICK_COUNT], eax + jmp VfRstDef_&Label + +.1: + /* Check if the debugger is enabled */ + cmp byte ptr __KdDebuggerEnabled, 0 + jnz 1f + + /* It isn't, bugcheck */ + push Info + push edi + push [edi+KINTERRUPT_SERVICE_CONTEXT] + push [edi+KINTERRUPT_SERVICE_ROUTINE] + push HARDWARE_INTERRUPT_STORM + call _KeBugCheckEx@20 + +1: + /* Debugger enabled, do a debug print + break instead */ + push [edi+KINTERRUPT_SERVICE_ROUTINE] + push offset _IsrOverflowMsg + call _DbgPrint + add esp, 8 + int 3 + + /* Breakpoint handled, get the new tick count */ + mov eax, _KeTickCount + and eax, 0xC0 + +VfRst_&Label: + /* Reset tick count */ + mov dword ptr [edi+KINTERRUPT_TICK_COUNT], eax + mov word ptr [edi+KINTERRUPT_DISPATCH_COUNT+2], 64 + +VfRstDef_&Label: + /* Put default overflow count and continue */ + mov ax, _KiISROverflow + mov word ptr [edi+KINTERRUPT_DISPATCH_COUNT], ax + jmp Vf_&Label + +VfWrap_&Label: + /* Check if we wrapped */ + add eax, 0x40 + cmp eax, [edi+KINTERRUPT_TICK_COUNT] + je Vf_&Label + + /* We did, start over */ + mov eax, _KeTickCount + jmp VfRst_&Label +.endm + +#else + +/* We don't verify interrupts on retail builds */ +.macro VERIFY_INT Label +.endm +.macro VERIFY_INT_END Label, Info +.endm + +#endif + +
Modified: trunk/reactos/ntoskrnl/ke/i386/irqobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/irqobj.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/irqobj.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/irqobj.c Mon Mar 19 06:29:29 2007 @@ -9,11 +9,16 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */
-/* INCLUDES ****************************************************************/ +/* INCLUDES *****************************************************************/
#include <ntoskrnl.h> #define NDEBUG #include <debug.h> + +/* GLOBALS *******************************************************************/ + +ULONG KiISRTimeout = 55; +USHORT KiISROverflow = 30000;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -172,6 +177,8 @@ Interrupt->ShareVector = ShareVector; Interrupt->Number = ProcessorNumber; Interrupt->FloatingSave = FloatingSave; + Interrupt->TickCount = (ULONG)-1; + Interrupt->DispatchCount = (ULONG)-1;
/* Loop the template in memory */ for (i = 0; i < KINTERRUPT_DISPATCH_CODES; i++) @@ -179,6 +186,14 @@ /* Copy the dispatch code */ *DispatchCode++ = KiInterruptTemplate[i]; } + + /* Sanity check */ + DPRINT1("Template Size: %lx. Code Size: %lx\n", + (ULONG_PTR)&KiInterruptTemplateDispatch - + (ULONG_PTR)KiInterruptTemplate, + KINTERRUPT_DISPATCH_CODES * 4); + ASSERT((ULONG_PTR)&KiInterruptTemplateDispatch - + (ULONG_PTR)KiInterruptTemplate <= (KINTERRUPT_DISPATCH_CODES * 4));
/* Jump to the last 4 bytes */ Patch = (PULONG)((ULONG_PTR)Patch + @@ -216,7 +231,6 @@ (Interrupt->SynchronizeIrql < Irql) || (Interrupt->FloatingSave)) { - DPRINT1("Invalid interrupt object\n"); return FALSE; }
@@ -254,7 +268,7 @@ (Dispatch.Interrupt->Mode == Interrupt->Mode)) { /* The vector is shared and the interrupts are compatible */ - ASSERT(FALSE); // FIXME: NOT YET SUPPORTED/TESTED + while (TRUE); // FIXME: NOT YET SUPPORTED/TESTED Interrupt->Connected = Connected = TRUE; ASSERT(Irql <= SYNCH_LEVEL);
@@ -274,6 +288,14 @@ /* Unlock the dispatcher and revert affinity */ KiReleaseDispatcherLock(OldIrql); KeRevertToUserAffinityThread(); + + /* Check if we failed while trying to connect */ + if ((Connected) && (Error)) + { + DPRINT1("HalEnableSystemInterrupt failed\n"); + KeDisconnectInterrupt(Interrupt); + Connected = FALSE; + }
/* Return to caller */ return Connected;
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/trap.s (original) +++ trunk/reactos/ntoskrnl/ke/i386/trap.s Mon Mar 19 06:29:29 2007 @@ -93,6 +93,12 @@ _UnhandledMsg: .asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
+_IsrTimeoutMsg: + .asciz "\n*** ISR at %lx took over .5 second\n" + +_IsrOverflowMsg: + .asciz "\n*** ISR at %lx appears to have an interrupt storm\n" + _KiTrapPrefixTable: .byte 0xF2 /* REP */ .byte 0xF3 /* REP INS/OUTS */ @@ -174,7 +180,7 @@ jnz NotWin32K
/* Get the TEB */ - mov ecx, [fs:KPCR_TEB] + mov ecx, PCR[KPCR_TEB]
/* Check if we should flush the User Batch */ xor ebx, ebx @@ -191,7 +197,7 @@
NotWin32K: /* Increase total syscall count */ - inc dword ptr fs:[KPCR_SYSTEM_CALLS] + inc dword ptr PCR[KPCR_SYSTEM_CALLS]
#ifdef DBG /* Increase per-syscall count */ @@ -243,7 +249,7 @@ mov eax, esi /* Restore it */
/* Get our temporary current thread pointer for sanity check */ - mov ecx, fs:[KPCR_CURRENT_THREAD] + mov ecx, PCR[KPCR_CURRENT_THREAD]
/* Make sure that we are not attached and that APCs are not disabled */ mov dl, [ecx+KTHREAD_APC_STATE_INDEX] @@ -262,7 +268,7 @@ KeReturnFromSystemCall:
/* Get the Current Thread */ - mov ecx, [fs:KPCR_CURRENT_THREAD] + mov ecx, PCR[KPCR_CURRENT_THREAD]
/* Restore the old trap frame pointer */ mov edx, [ebp+KTRAP_FRAME_EDX] @@ -353,7 +359,7 @@ BadStack:
/* Restore ESP0 stack */ - mov ecx, [fs:KPCR_TSS] + mov ecx, PCR[KPCR_TSS] mov esp, ss:[ecx+KTSS_ESP0]
/* Generate V86M Stack for Trap 6 */ @@ -373,10 +379,10 @@ #ifdef DBG InvalidIrql: /* Save current IRQL */ - push fs:[KPCR_IRQL] + push PCR[KPCR_IRQL]
/* Set us at passive */ - mov dword ptr fs:[KPCR_IRQL], 0 + mov dword ptr PCR[KPCR_IRQL], 0 cli
/* Bugcheck */ @@ -485,7 +491,7 @@ push ebp
/* Get the current thread and restore its trap frame */ - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov edx, [ebp+KTRAP_FRAME_EDX] mov [ebx+KTHREAD_TRAP_FRAME], edx
@@ -497,7 +503,7 @@
/* Get the exception list and restore */ mov eax, [ebx+KTRAP_FRAME_EXCEPTION_LIST] - mov [fs:KPCR_EXCEPTION_LIST], eax + mov PCR[KPCR_EXCEPTION_LIST], eax
/* Get the parameters */ mov edx, [ebp+16] /* Search frames */ @@ -532,7 +538,7 @@ push ebp
/* Get the current thread and restore its trap frame */ - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov edx, [ebp+KTRAP_FRAME_EDX] mov [ebx+KTHREAD_TRAP_FRAME], edx
@@ -696,7 +702,7 @@
VdmCheck: /* Check if this is a VDM process */ - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 jz SendException @@ -742,7 +748,7 @@
V86Int1: /* Check if this is a VDM process */ - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 jz EnableInterrupts @@ -806,7 +812,7 @@
V86Int3: /* Check if this is a VDM process */ - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 jz EnableInterrupts3 @@ -847,7 +853,7 @@
VdmCheck4: /* Check if this is a VDM process */ - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 jz SendException4 @@ -893,7 +899,7 @@
VdmCheck5: /* Check if this is a VDM process */ - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 jz SendException5 @@ -934,7 +940,7 @@ jz UmodeOpcode
/* Check if the process is vDM */ - mov ebx, fs:[KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 jnz IsVdmOpcode @@ -950,8 +956,8 @@ /* Setup a SEH frame */ push ebp push OpcodeSEH - push fs:[KPCR_EXCEPTION_LIST] - mov fs:[KPCR_EXCEPTION_LIST], esp + push PCR[KPCR_EXCEPTION_LIST] + mov PCR[KPCR_EXCEPTION_LIST], esp
OpcodeLoop: /* Get the instruction and check if it's LOCK */ @@ -964,7 +970,7 @@ loop OpcodeLoop
/* Undo SEH frame */ - pop fs:[KPCR_EXCEPTION_LIST] + pop PCR[KPCR_EXCEPTION_LIST] add esp, 8
KmodeOpcode: @@ -980,7 +986,7 @@ LockCrash:
/* Undo SEH Frame */ - pop fs:[KPCR_EXCEPTION_LIST] + pop PCR[KPCR_EXCEPTION_LIST] add esp, 8
/* Setup invalid lock exception and dispatch it */ @@ -1000,7 +1006,7 @@
/* Get SEH frame */ mov esp, [esp+8] - pop fs:[KPCR_EXCEPTION_LIST] + pop PCR[KPCR_EXCEPTION_LIST] add esp, 4 pop ebp
@@ -1030,7 +1036,7 @@
/* Get the current thread and stack */ StartTrapHandle: - mov eax, [fs:KPCR_CURRENT_THREAD] + mov eax, PCR[KPCR_CURRENT_THREAD] mov ecx, [eax+KTHREAD_INITIAL_STACK] sub ecx, NPX_FRAME_LENGTH
@@ -1049,7 +1055,7 @@ mov cr0, ebx
/* Check the NPX thread */ - mov edx, [fs:KPCR_NPX_THREAD] + mov edx, PCR[KPCR_NPX_THREAD] or edx, edx jz NoNpxThread
@@ -1083,7 +1089,7 @@ AfterRestore: /* Set state loaded */ mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_LOADED - mov [fs:KPCR_NPX_THREAD], eax + mov PCR[KPCR_NPX_THREAD], eax
/* Enable interrupts to happen now */ sti @@ -1144,7 +1150,7 @@
UserNpx: /* Get the current thread */ - mov eax, fs:[KPCR_CURRENT_THREAD] + mov eax, PCR[KPCR_CURRENT_THREAD]
/* Check NPX state */ cmp byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED @@ -1180,7 +1186,7 @@
/* Update NPX state */ mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED - mov dword ptr fs:[KPCR_NPX_THREAD], 0 + mov dword ptr PCR[KPCR_NPX_THREAD], 0
NoSaveRestore: /* Clear the TS bit and re-enable interrupts */ @@ -1293,7 +1299,7 @@
V86Npx: /* Check if this is a VDM */ - mov eax, fs:[KPCR_CURRENT_THREAD] + mov eax, PCR[KPCR_CURRENT_THREAD] mov ebx, [eax+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 jz HandleUserNpx @@ -1414,7 +1420,7 @@
/* Setup SEH handler frame */ mov esp, [esp+8] - pop fs:[KPCR_EXCEPTION_LIST] + pop PCR[KPCR_EXCEPTION_LIST] add esp, 4 pop ebp
@@ -1445,7 +1451,7 @@ V86_TRAP_PROLOG kitd
/* Make sure that this is a V86 process */ - mov ecx, [fs:KPCR_CURRENT_THREAD] + mov ecx, PCR[KPCR_CURRENT_THREAD] mov ecx, [ecx+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [ecx+EPROCESS_VDM_OBJECTS], 0 jnz RaiseIrql @@ -1505,7 +1511,7 @@ jnz UserModeGpf
/* Check if we have a VDM alert */ - cmp dword ptr fs:[KPCR_VDM_ALERT], 0 + cmp dword ptr PCR[KPCR_VDM_ALERT], 0 jnz VdmAlertGpf
/* Check for GPF during GPF */ @@ -1565,7 +1571,7 @@
NotBiosGpf: /* Check if the thread was in kernel mode */ - mov ebx, [fs:KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] test byte ptr [ebx+KTHREAD_PREVIOUS_MODE], 0xFF jz UserModeGpf
@@ -1656,7 +1662,7 @@ jz _KiSystemFatalException
/* Get the process and check which CS this came from */ - mov ebx, fs:[KPCR_CURRENT_THREAD] + mov ebx, PCR[KPCR_CURRENT_THREAD] mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS] cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK jz CheckVdmGpf @@ -1719,8 +1725,8 @@ /* Setup a SEH handler */ push ebp push offset _KiTrapExceptHandler - push fs:[KPCR_EXCEPTION_LIST] - mov fs:[KPCR_EXCEPTION_LIST], esp + push PCR[KPCR_EXCEPTION_LIST] + mov PCR[KPCR_EXCEPTION_LIST], esp
/* Get EIP */ mov esi, [ebp+KTRAP_FRAME_EIP] @@ -1790,7 +1796,7 @@
IsPrivInstruction: /* Cleanup the SEH frame */ - pop fs:[KPCR_EXCEPTION_LIST] + pop PCR[KPCR_EXCEPTION_LIST] add esp, 8
/* Setup the exception */ @@ -1800,7 +1806,7 @@
NotIoViolation: /* Cleanup the SEH frame */ - pop fs:[KPCR_EXCEPTION_LIST] + pop PCR[KPCR_EXCEPTION_LIST] add esp, 8
SetException: @@ -1824,11 +1830,11 @@ TRAP_PROLOG kit14
/* Check if we have a VDM alert */ - cmp dword ptr fs:[KPCR_VDM_ALERT], 0 + cmp dword ptr PCR[KPCR_VDM_ALERT], 0 jnz VdmAlertGpf
/* Get the current thread */ - mov edi, fs:[KPCR_CURRENT_THREAD] + mov edi, PCR[KPCR_CURRENT_THREAD]
/* Get the stack address of the frame */ lea eax, [esp+KTRAP_FRAME_LENGTH+NPX_FRAME_LENGTH] @@ -1840,7 +1846,7 @@ jb NoFixUp
/* Check if we have a TEB */ - mov eax, fs:[KPCR_TEB] + mov eax, PCR[KPCR_TEB] or eax, eax jle NoFixUp
@@ -1913,7 +1919,7 @@ jnz VdmPF
/* Check if the fault occured in a VDM */ - mov esi, fs:[KPCR_CURRENT_THREAD] + mov esi, PCR[KPCR_CURRENT_THREAD] mov esi, [esi+KTHREAD_APCSTATE_PROCESS] cmp dword ptr [esi+EPROCESS_VDM_OBJECTS], 0 jz CheckStatus @@ -2006,8 +2012,8 @@ TRAP_PROLOG kit16
/* Check if this is the NPX Thread */ - mov eax, fs:[KPCR_CURRENT_THREAD] - cmp eax, fs:[KPCR_NPX_THREAD] + mov eax, PCR[KPCR_CURRENT_THREAD] + cmp eax, PCR[KPCR_NPX_THREAD]
/* Get the initial stack and NPX frame */ mov ecx, [eax+KTHREAD_INITIAL_STACK] @@ -2059,7 +2065,7 @@ _KiCoprocessorError@0:
/* Get the NPX Thread's Initial stack */ - mov eax, [fs:KPCR_NPX_THREAD] + mov eax, PCR[KPCR_NPX_THREAD] mov eax, [eax+KTHREAD_INITIAL_STACK]
/* Make space for the FPU Save area */ @@ -2085,7 +2091,7 @@ push esp
/* Go to kernel mode thread stack */ - mov eax, fs:[KPCR_CURRENT_THREAD] + mov eax, PCR[KPCR_CURRENT_THREAD] add esp, [eax+KTHREAD_INITIAL_STACK]
/* Switch to good stack segment */ @@ -2112,7 +2118,7 @@ INT_PROLOG kui, DoNotPushFakeErrorCode
/* Increase interrupt count */ - inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT] + inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
/* Put vector in EBX and make space for KIRQL */ mov ebx, [esp] @@ -2161,7 +2167,7 @@ _KiDispatchInterrupt@0:
/* Get the PCR and disable interrupts */ - mov ebx, [fs:KPCR_SELF] + mov ebx, PCR[KPCR_SELF] cli
/* Check if we have to deliver DPCs, timers, or deferred threads */ @@ -2281,7 +2287,7 @@ _KiChainedDispatch@0:
/* Increase interrupt count */ - inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT] + inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
/* Save trap frame */ mov ebp, esp @@ -2308,17 +2314,14 @@ call _KiChainedDispatch2ndLvl@0
/* Exit the interrupt */ - mov esi, $ - cli - call _HalEndSystemInterrupt@8 - jmp _Kei386EoiHelper@0 + INT_EPILOG 0 .endfunc
.func KiInterruptDispatch@0 _KiInterruptDispatch@0:
/* Increase interrupt count */ - inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT] + inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
/* Save trap frame */ mov ebp, esp @@ -2346,27 +2349,51 @@ mov esi, [edi+KINTERRUPT_ACTUAL_LOCK] ACQUIRE_SPINLOCK(esi, IntSpin)
+ /* Make sure that this interrupt isn't storming */ + VERIFY_INT kid + + /* Save the tick count */ + mov ebx, _KeTickCount + /* Call the ISR */ mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT] push eax push edi call [edi+KINTERRUPT_SERVICE_ROUTINE]
+ /* Check if the ISR timed out */ + add ebx, _KiISRTimeout + cmp _KeTickCount, ebx + jnc IsrTimeout + +ReleaseLock: /* Release the lock */ RELEASE_SPINLOCK(esi)
/* Exit the interrupt */ - cli - call _HalEndSystemInterrupt@8 - jmp _Kei386EoiHelper@0 + INT_EPILOG 0
SpuriousInt: /* Exit the interrupt */ add esp, 8 - jmp _Kei386EoiHelper@0 + INT_EPILOG 1
#ifdef CONFIG_SMP IntSpin: SPIN_ON_LOCK esi, GetIntLock #endif -.endfunc + +IsrTimeout: + /* Print warning message */ + push [edi+KINTERRUPT_SERVICE_ROUTINE] + push offset _IsrTimeoutMsg + call _DbgPrint + add esp,8 + + /* Break into debugger, then continue */ + int 3 + jmp ReleaseLock + + /* Cleanup verification */ + VERIFY_INT_END kid, 0 +.endfunc