- 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.

svn path=/trunk/; revision=26137
This commit is contained in:
Alex Ionescu 2007-03-19 03:29:29 +00:00
parent 42c0ac532c
commit 32ca724933
5 changed files with 245 additions and 78 deletions

View file

@ -222,10 +222,12 @@ Author:
//
#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 @@ Author:
#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 @@ Author:
#define MAXIMUM_IDTVECTOR 0xFF
#endif // !_ASM_H

View file

@ -622,14 +622,14 @@ typedef struct _KINTERRUPT
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;

View file

@ -353,7 +353,7 @@ _KiUnexpectedInterrupt&Number:
/* 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 @@ _KiUnexpectedInterrupt&Number:
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 @@ _KiUnexpectedInterrupt&Number:
1:
/* Get current thread */
mov ecx, [fs:KPCR_CURRENT_THREAD]
mov ecx, PCR[KPCR_CURRENT_THREAD]
cld
/* Flush DR7 */
@ -555,10 +555,10 @@ _KiUnexpectedInterrupt&Number:
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 @@ _KiUnexpectedInterrupt&Number:
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 @@ _KiUnexpectedInterrupt&Number:
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 @@ _KiUnexpectedInterrupt&Number:
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 @@ _KiUnexpectedInterrupt&Number:
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 @@ _KiUnexpectedInterrupt&Number:
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 @@ _KiUnexpectedInterrupt&Number:
/* 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 @@ PendingUserApc:
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 @@ PendingUserApc:
#endif
/* Restore it */
mov [fs:KPCR_EXCEPTION_LIST], edx
mov PCR[KPCR_EXCEPTION_LIST], edx
.if \RestorePreviousMode
/* Get previous mode */
@ -990,7 +990,7 @@ PendingUserApc:
#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 @@ FastExit:
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

View file

@ -9,12 +9,17 @@
* 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 *********************************************************/
VOID
@ -172,6 +177,8 @@ KeInitializeInterrupt(IN PKINTERRUPT Interrupt,
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++)
@ -180,6 +187,14 @@ KeInitializeInterrupt(IN PKINTERRUPT Interrupt,
*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 +
((ULONG_PTR)&KiInterruptTemplateObject -
@ -216,7 +231,6 @@ KeConnectInterrupt(IN PKINTERRUPT Interrupt)
(Interrupt->SynchronizeIrql < Irql) ||
(Interrupt->FloatingSave))
{
DPRINT1("Invalid interrupt object\n");
return FALSE;
}
@ -254,7 +268,7 @@ KeConnectInterrupt(IN PKINTERRUPT Interrupt)
(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);
@ -275,6 +289,14 @@ KeConnectInterrupt(IN PKINTERRUPT Interrupt)
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;
}

View file

@ -93,6 +93,12 @@ _UnexpectedMsg:
_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 @@ SharedCode:
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 @@ ReadBatch:
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 @@ AfterSysCall:
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 @@ SkipCheck:
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 @@ AccessViolation:
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 @@ BadStack:
#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 @@ _NtRaiseException@12:
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 @@ _NtRaiseException@12:
/* 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 @@ _NtContinue@8:
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 @@ SendException:
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 @@ PrepInt1:
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 @@ PrepInt3:
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 @@ SendException4:
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 @@ SendException5:
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 @@ NotV86UD:
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 @@ UmodeOpcode:
/* 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 @@ OpcodeLoop:
loop OpcodeLoop
/* Undo SEH frame */
pop fs:[KPCR_EXCEPTION_LIST]
pop PCR[KPCR_EXCEPTION_LIST]
add esp, 8
KmodeOpcode:
@ -980,7 +986,7 @@ KmodeOpcode:
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 @@ OpcodeSEH:
/* 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 @@ _KiTrap7:
/* 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 @@ CheckState:
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 @@ FrRestore:
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 @@ HandleNpxFault:
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 @@ MakeCr0Dirty:
/* 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 @@ UnexpectedNpx:
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 @@ _KiTrapExceptHandler:
/* 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 @@ _KiTrap13:
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 @@ NotV86:
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 @@ KmodeGpf:
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 @@ UserModeGpf:
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 @@ CheckPrivilegedInstruction:
/* 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 @@ CheckPrivilegedInstruction2:
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 @@ IsPrivInstruction:
NotIoViolation:
/* Cleanup the SEH frame */
pop fs:[KPCR_EXCEPTION_LIST]
pop PCR[KPCR_EXCEPTION_LIST]
add esp, 8
SetException:
@ -1824,11 +1830,11 @@ _KiTrap14:
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 @@ _KiTrap14:
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 @@ CheckVdmPf:
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 @@ _KiTrap16:
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 @@ _KiSystemFatalException:
_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 @@ _Ki16BitStackException:
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 @@ _KiUnexpectedInterruptTail:
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 @@ _KiUnexpectedInterrupt:
_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 @@ _KiChainedDispatch2ndLvl@0:
_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 @@ _KiChainedDispatch@0:
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 @@ GetIntLock:
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
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