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=2613…
==============================================================================
--- 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=…
==============================================================================
--- 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/…
==============================================================================
--- 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?…
==============================================================================
--- 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(a)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?re…
==============================================================================
--- 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