From 8b4c009bfbaa72bf5f3d1f2025f541e100006715 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sat, 2 Dec 2006 20:49:56 +0000 Subject: [PATCH] - Implement V86 trap fixup during traps and interrupts. - Implement DR register save/restore during traps, interrupts and system calls. - Remove respective entry from krnlfun.c. svn path=/trunk/; revision=25020 --- reactos/include/ndk/asm.h | 10 + reactos/ntoskrnl/KrnlFun.c | 1 - .../ntoskrnl/include/internal/i386/asmmacro.S | 242 ++++++++++++++++-- reactos/ntoskrnl/ke/i386/trap.s | 176 ++++++------- 4 files changed, 313 insertions(+), 116 deletions(-) diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index b4c9177c8bd..831fcf340af 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -136,6 +136,16 @@ Author: #define KPROCESS_ACTIVE_PROCESSORS 0x34 #define EPROCESS_VDM_OBJECTS 0x144 +// +// KPRCB Offsets +// +#define KPRCB_DR0 0x2F8 +#define KPRCB_DR1 0x2FC +#define KPRCB_DR2 0x300 +#define KPRCB_DR3 0x304 +#define KPRCB_DR6 0x308 +#define KPRCB_DR7 0x20C + // // KPCR Offsets // diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index 7a45073b8d8..279c31c7c87 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -28,7 +28,6 @@ // // Ke: // - Figure out why the DPC stack doesn't really work. -// - Add DR macro/save and VM macro/save. // - New optimized table-based tick-hashed timer implementation. // - New Thread Scheduler based on 2003. // - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion. diff --git a/reactos/ntoskrnl/include/internal/i386/asmmacro.S b/reactos/ntoskrnl/include/internal/i386/asmmacro.S index d67c7aa7888..cb6d8093977 100644 --- a/reactos/ntoskrnl/include/internal/i386/asmmacro.S +++ b/reactos/ntoskrnl/include/internal/i386/asmmacro.S @@ -186,6 +186,104 @@ _KiUnexpectedInterrupt&Number: jmp $ .endm +// +// @name V86_TRAP_FIXUP +// +// This macro sets up the debug header in the trap frame. +// +// @param None. +// +// @remark ebp = PKTRAP_FRAME +// +.macro V86_TRAP_FIXUP + /* Get V86 segment registers */ + mov eax, [ebp+KTRAP_FRAME_V86_FS] + mov ebx, [ebp+KTRAP_FRAME_V86_GS] + mov ecx, [ebp+KTRAP_FRAME_V86_ES] + mov edx, [ebp+KTRAP_FRAME_V86_DS] + + /* Restore them into Protected Mode trap frame */ + mov [ebp+KTRAP_FRAME_FS], ax + mov [ebp+KTRAP_FRAME_GS], bx + mov [ebp+KTRAP_FRAME_ES], cx + mov [ebp+KTRAP_FRAME_DS], dx + + /* Go back to mainline code */ + jmp 1f +.endm + +// +// @name DR_TRAP_FIXUP +// +// This macro sets up the debug header in the trap frame. +// +// @param None. +// +// @remark ebp = PKTRAP_FRAME +// +.macro DR_TRAP_FIXUP + /* Check if this was V86 mode */ + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jnz 2f + + /* Check if it was user mode */ + test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK + jz 3f + +2: + /* Get DR0, 1, 2 */ + mov ebx, dr0 + mov ecx, dr1 + mov edi, dr2 + + /* Save them */ + mov [ebp+KTRAP_FRAME_DR0], ebx + mov [ebp+KTRAP_FRAME_DR1], ecx + mov [ebp+KTRAP_FRAME_DR2], edi + + /* Get DR3, 6, 7 */ + mov ebx, dr0 + mov ecx, dr1 + mov edi, dr2 + + /* Save them */ + mov [ebp+KTRAP_FRAME_DR3], ebx + mov [ebp+KTRAP_FRAME_DR6], ecx + mov [ebp+KTRAP_FRAME_DR7], edi + + /* Clear DR7 */ + xor ebx, ebx + mov dr7, ebx + + /* Get the PRCB */ + mov edi, PCR[KPCR_PRCB] + + /* Get DR0, 1 */ + mov ebx, [edi+KPRCB_DR0] + mov ecx, [edi+KPRCB_DR1] + + /* Set them */ + mov dr0, ebx + mov dr1, ecx + + /* Get DR2, 3 */ + mov ebx, [edi+KPRCB_DR2] + mov ecx, [edi+KPRCB_DR3] + + /* Set them */ + mov dr2, ebx + mov dr3, ecx + + /* Get DR6, 7 */ + mov ebx, [edi+KPRCB_DR6] + mov ecx, [edi+KPRCB_DR7] + + /* Set them */ + mov dr6, ebx + mov dr7, ecx + jz 3f +.endm + // // @name SET_TF_DEBUG_HEADER // @@ -315,6 +413,7 @@ _KiUnexpectedInterrupt&Number: /* Save FS and set it to PCR */ push fs mov ebx, KGDT_R0_PCR + .byte 0x66 mov fs, bx /* Save exception list and bogus previous mode */ @@ -336,16 +435,23 @@ _KiUnexpectedInterrupt&Number: sub esp, 0x30 /* Load the segment registers */ + .byte 0x66 mov ds, ax + .byte 0x66 mov es, ax + /* Check if this interrupt happened in 16-bit mode */ + cmp esp, 0x10000 + jb _Ki16BitStackException + /* Set up frame */ mov ebp, esp /* Check if this was from V86 Mode */ - /* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK; */ - /* jnz V86_Label; */ + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jnz V86_&Label +1: /* Get current thread */ mov ecx, [fs:KPCR_CURRENT_THREAD] cld @@ -353,9 +459,10 @@ _KiUnexpectedInterrupt&Number: /* Flush DR7 */ and dword ptr [ebp+KTRAP_FRAME_DR7], 0 +3: /* Check if the thread was being debugged */ - /* test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF; */ - /* jnz Dr_Label; */ + test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF + jnz Dr_&Label /* Set the Trap Frame Debug Header */ SET_TF_DEBUG_HEADER @@ -399,10 +506,11 @@ _KiUnexpectedInterrupt&Number: mov dword ptr [esp+KTRAP_FRAME_PREVIOUS_MODE], -1 /* Check if this was from V86 Mode */ - /* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK */ - /* jnz V86_&Label*/ + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jnz V86_&Label /* Check if this was kernel mode */ +1: cmp dword ptr [esp+KTRAP_FRAME_CS], KGDT_R0_CODE jz 1f @@ -463,9 +571,10 @@ _KiUnexpectedInterrupt&Number: .endif /* Save DR registers if needed */ - //jnz Dr_&Label + jnz Dr_&Label /* Set the trap frame debug header */ +3: SET_TF_DEBUG_HEADER .endm @@ -484,7 +593,7 @@ _KiUnexpectedInterrupt&Number: // // @remark None. // -.macro SYSCALL_PROLOG +.macro SYSCALL_PROLOG Label /* Create a trap frame */ push 0 push ebp @@ -495,6 +604,7 @@ _KiUnexpectedInterrupt&Number: /* Load PCR Selector into fs */ mov ebx, KGDT_R0_PCR + .byte 0x66 mov fs, bx /* Get a pointer to the current thread */ @@ -507,19 +617,15 @@ _KiUnexpectedInterrupt&Number: mov dword ptr [fs:KPCR_EXCEPTION_LIST], -1 /* Save the old previous mode */ - push ss:[esi+KTHREAD_PREVIOUS_MODE] + push [esi+KTHREAD_PREVIOUS_MODE] /* Skip the other registers */ sub esp, 0x48 - /* Hack: it seems that on VMWare someone damages ES/DS on exit. Investigate! */ - mov [esp+KTRAP_FRAME_DS], ds - mov [esp+KTRAP_FRAME_ES], es - /* Set the new previous mode based on the saved CS selector */ mov ebx, [esp+0x6C] and ebx, 1 - mov byte ptr ss:[esi+KTHREAD_PREVIOUS_MODE], bl + mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], bl /* Go on the Kernel stack frame */ mov ebp, esp @@ -539,9 +645,108 @@ _KiUnexpectedInterrupt&Number: cld /* Save DR registers if needed */ - //jnz Dr_kss_&Label + jnz Dr_&Label /* Set the trap frame debug header */ +3: + SET_TF_DEBUG_HEADER + + /* Enable interrupts */ + sti +.endm + +// +// @name FASTCALL_PROLOG +// +// TODO +// +// @param Label +// Unique label identifying the name of the caller function; will be +// used to append to the name of the DR helper function, which must +// already exist. +// +// @remark None. +// +.macro FASTCALL_PROLOG Label + /* Set FS to PCR */ + mov ecx, KGDT_R0_PCR + mov fs, cx + //push KGDT_R0_PCR + //pop fs + + /* Set user selector */ + mov ecx, KGDT_R3_DATA | RPL_MASK + + /* Set DS/ES to User Selector */ + mov ds, cx + mov es, cx + + /* Set the current stack to Kernel Stack */ + mov ecx, [fs:KPCR_TSS] + mov esp, [ecx+KTSS_ESP0] + + /* Set up a fake INT Stack. */ + push KGDT_R3_DATA + RPL_MASK + push edx /* Ring 3 SS:ESP */ + pushf /* Ring 3 EFLAGS */ + push 2 /* Ring 0 EFLAGS */ + add edx, 8 /* Skip user parameter list */ + popf /* Set our EFLAGS */ + or dword ptr [esp], EFLAGS_INTERRUPT_MASK /* Re-enable IRQs in EFLAGS, to fake INT */ + push KGDT_R3_CODE + RPL_MASK + push dword ptr ds:KUSER_SHARED_SYSCALL_RET + + /* Setup the Trap Frame stack */ + push 0 + push ebp + push ebx + push esi + push edi + push KGDT_R3_TEB + RPL_MASK + + /* Save pointer to our PCR */ + mov ebx, [fs:KPCR_SELF] + + /* Get a pointer to the current thread */ + mov esi, [ebx+KPCR_CURRENT_THREAD] + + /* Set the exception handler chain terminator */ + push [ebx+KPCR_EXCEPTION_LIST] + mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1 + + /* Use the thread's stack */ + mov ebp, [esi+KTHREAD_INITIAL_STACK] + + /* Push previous mode */ + push UserMode + + /* Skip the other registers */ + sub esp, 0x48 + + /* Make space for us on the stack */ + sub ebp, 0x29C + + /* Write the previous mode */ + mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], UserMode + + /* Sanity check */ + cmp ebp, esp + jnz BadStack + + /* Flush DR7 */ + and dword ptr [ebp+KTRAP_FRAME_DR7], 0 + + /* Check if the thread was being debugged */ + test byte ptr [esi+KTHREAD_DEBUG_ACTIVE], 0xFF + + /* Set the thread's trap frame */ + mov [esi+KTHREAD_TRAP_FRAME], ebp + + /* Save DR registers if needed */ + jnz Dr_&Label + + /* Set the trap frame debug header */ +3: SET_TF_DEBUG_HEADER /* Enable interrupts */ @@ -966,6 +1171,13 @@ FastExit: mov esi, [esp+KTRAP_FRAME_EIP] mov [ebx], esi +.if \RestoreVolatiles + /* Restore volatiles */ + mov eax, [esp+KTRAP_FRAME_EAX] + mov edx, [esp+KTRAP_FRAME_EDX] + mov ecx, [esp+KTRAP_FRAME_ECX] +.endif + /* Return */ add esp, KTRAP_FRAME_EDI pop edi diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 0e7865b3185..8288c2cc170 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -96,100 +96,22 @@ _KiRaiseAssertion: int 3 .func KiSystemService +Dr_kss: DR_TRAP_FIXUP _KiSystemService: /* Enter the shared system call prolog */ - SYSCALL_PROLOG + SYSCALL_PROLOG kss /* Jump to the actual handler */ jmp SharedCode .endfunc .func KiFastCallEntry +Dr_FastCallDrSave: DR_TRAP_FIXUP _KiFastCallEntry: - /* Set FS to PCR */ - mov ecx, KGDT_R0_PCR - mov fs, cx - //push KGDT_R0_PCR - //pop fs - - /* Set user selector */ - mov ecx, KGDT_R3_DATA | RPL_MASK - - /* Set DS/ES to User Selector */ - mov ds, cx - mov es, cx - - /* Set the current stack to Kernel Stack */ - mov ecx, [fs:KPCR_TSS] - mov esp, ss:[ecx+KTSS_ESP0] - - /* Set up a fake INT Stack. */ - push KGDT_R3_DATA + RPL_MASK - push edx /* Ring 3 SS:ESP */ - pushf /* Ring 3 EFLAGS */ - push 2 /* Ring 0 EFLAGS */ - add edx, 8 /* Skip user parameter list */ - popf /* Set our EFLAGS */ - or dword ptr [esp], EFLAGS_INTERRUPT_MASK /* Re-enable IRQs in EFLAGS, to fake INT */ - push KGDT_R3_CODE + RPL_MASK - push dword ptr ds:KUSER_SHARED_SYSCALL_RET - - /* Setup the Trap Frame stack */ - push 0 - push ebp - push ebx - push esi - push edi - push KGDT_R3_TEB + RPL_MASK - - /* Save pointer to our PCR */ - mov ebx, [fs:KPCR_SELF] - - /* Get a pointer to the current thread */ - mov esi, [ebx+KPCR_CURRENT_THREAD] - - /* Set the exception handler chain terminator */ - push [ebx+KPCR_EXCEPTION_LIST] - mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1 - - /* Use the thread's stack */ - mov ebp, [esi+KTHREAD_INITIAL_STACK] - - /* Push previous mode */ - push UserMode - - /* Skip the other registers */ - sub esp, 0x48 - - /* Make space for us on the stack */ - sub ebp, 0x29C - - /* Write the previous mode */ - mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], UserMode - - /* Sanity check */ - cmp ebp, esp - jnz BadStack - - /* Flush DR7 */ - and dword ptr [ebp+KTRAP_FRAME_DR7], 0 - - /* Check if the thread was being debugged */ - test byte ptr [esi+KTHREAD_DEBUG_ACTIVE], 0xFF - - /* Set the thread's trap frame */ - mov [esi+KTHREAD_TRAP_FRAME], ebp - - /* Save DR registers if needed */ - //jnz Dr_FastCallDrSave - - /* Set the trap frame debug header */ - SET_TF_DEBUG_HEADER - - /* Enable interrupts */ - sti + /* Enter the fast system call prolog */ + FASTCALL_PROLOG FastCallDrSave SharedCode: @@ -514,13 +436,15 @@ AbiosExit: int 3 .func KiDebugService +Dr_kids: DR_TRAP_FIXUP +V86_kids: V86_TRAP_FIXUP _KiDebugService: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(kids) + TRAP_PROLOG kids /* Increase EIP so we skip the INT3 */ //inc dword ptr [ebp+KTRAP_FRAME_EIP] @@ -749,12 +673,14 @@ _DispatchTwoParam: /* HARDWARE TRAP HANDLERS ****************************************************/ .func KiTrap0 +Dr_kit0: DR_TRAP_FIXUP +V86_kit0: V86_TRAP_FIXUP _KiTrap0: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(0) + TRAP_PROLOG kit0 /* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -788,12 +714,14 @@ V86Int0: .endfunc .func KiTrap1 +Dr_kit1: DR_TRAP_FIXUP +V86_kit1: V86_TRAP_FIXUP _KiTrap1: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(1) + TRAP_PROLOG kit1 /* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -839,12 +767,14 @@ _KiTrap2: .endfunc .func KiTrap3 +Dr_kit3: DR_TRAP_FIXUP +V86_kit3: V86_TRAP_FIXUP _KiTrap3: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(3) + TRAP_PROLOG kit3 /* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -887,12 +817,14 @@ V86Int3: .endfunc .func KiTrap4 +Dr_kit4: DR_TRAP_FIXUP +V86_kit4: V86_TRAP_FIXUP _KiTrap4: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(4) + TRAP_PROLOG kit4 /* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -927,12 +859,14 @@ V86Int4: .endfunc .func KiTrap5 +Dr_kit5: DR_TRAP_FIXUP +V86_kit5: V86_TRAP_FIXUP _KiTrap5: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(5) + TRAP_PROLOG kit5 /* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -971,6 +905,8 @@ V86Int5: .endfunc .func KiTrap6 +Dr_kit6: DR_TRAP_FIXUP +V86_kit6: V86_TRAP_FIXUP _KiTrap6: /* It this a V86 GPF? */ @@ -989,7 +925,7 @@ NotV86UD: push 0 /* Enter trap */ - TRAP_PROLOG(6) + TRAP_PROLOG kit6 /* Check if this happened in kernel mode */ test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK @@ -1086,12 +1022,14 @@ OpcodeSEH: .endfunc .func KiTrap7 +Dr_kit7: DR_TRAP_FIXUP +V86_kit7: V86_TRAP_FIXUP _KiTrap7: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(7) + TRAP_PROLOG kit7 /* Get the current thread and stack */ StartTrapHandle: @@ -1405,12 +1343,14 @@ _KiTrap8: .endfunc .func KiTrap9 +Dr_kit9: DR_TRAP_FIXUP +V86_kit9: V86_TRAP_FIXUP _KiTrap9: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(9) + TRAP_PROLOG kit9 /* Enable interrupts and bugcheck */ sti @@ -1419,9 +1359,11 @@ _KiTrap9: .endfunc .func KiTrap10 +Dr_kit10: DR_TRAP_FIXUP +V86_kit10: V86_TRAP_FIXUP _KiTrap10: /* Enter trap */ - TRAP_PROLOG(10) + TRAP_PROLOG kit10 /* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -1448,9 +1390,11 @@ Fatal: .endfunc .func KiTrap11 +Dr_kit11: DR_TRAP_FIXUP +V86_kit11: V86_TRAP_FIXUP _KiTrap11: /* Enter trap */ - TRAP_PROLOG(11) + TRAP_PROLOG kit11 /* FIXME: ROS Doesn't handle segment faults yet */ mov eax, 11 @@ -1458,9 +1402,11 @@ _KiTrap11: .endfunc .func KiTrap12 +Dr_kit12: DR_TRAP_FIXUP +V86_kit12: V86_TRAP_FIXUP _KiTrap12: /* Enter trap */ - TRAP_PROLOG(12) + TRAP_PROLOG kit12 /* FIXME: ROS Doesn't handle stack faults yet */ mov eax, 12 @@ -1468,6 +1414,8 @@ _KiTrap12: .endfunc .func KiTrap13 +Dr_kitd: DR_TRAP_FIXUP +V86_kitd: V86_TRAP_FIXUP _KiTrap13: /* It this a V86 GPF? */ @@ -1531,7 +1479,7 @@ NotV86Trap: NotV86: /* Enter trap */ - TRAP_PROLOG(13) + TRAP_PROLOG kitd /* Check if this was from kernel-mode */ test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK @@ -1678,9 +1626,11 @@ UserModeGpf: .endfunc .func KiTrap14 +Dr_kit14: DR_TRAP_FIXUP +V86_kit14: V86_TRAP_FIXUP _KiTrap14: /* Enter trap */ - TRAP_PROLOG(14) + TRAP_PROLOG kit14 /* Call the C exception handler */ push 14 @@ -1693,12 +1643,14 @@ _KiTrap14: .endfunc .func KiTrap0F +Dr_kit15: DR_TRAP_FIXUP +V86_kit15: V86_TRAP_FIXUP _KiTrap0F: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(15) + TRAP_PROLOG kit15 sti /* Raise a fatal exception */ @@ -1707,12 +1659,14 @@ _KiTrap0F: .endfunc .func KiTrap16 +Dr_kit16: DR_TRAP_FIXUP +V86_kit16: V86_TRAP_FIXUP _KiTrap16: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(16) + TRAP_PROLOG kit16 /* Check if this is the NPX Thread */ mov eax, fs:[KPCR_CURRENT_THREAD] @@ -1732,12 +1686,14 @@ _KiTrap16: .endfunc .func KiTrap17 +Dr_kit17: DR_TRAP_FIXUP +V86_kit17: V86_TRAP_FIXUP _KiTrap17: /* Push error code */ push 0 /* Enter trap */ - TRAP_PROLOG(17) + TRAP_PROLOG kit17 /* FIXME: ROS Doesn't handle alignment faults yet */ mov eax, 17 @@ -1784,6 +1740,22 @@ _KiCoprocessorError@0: ret .endfunc +.func Ki16BitStackException +_Ki16BitStackException: + + /* Save stack */ + push ss + push esp + + /* Go to kernel mode thread stack */ + mov eax, fs:[KPCR_CURRENT_THREAD] + add esp, [eax+KTHREAD_INITIAL_STACK] + + /* Switch to good stack segment */ + /* TODO */ + int 3 +.endfunc + /* UNEXPECTED INTERRUPT HANDLERS **********************************************/ .globl _KiStartUnexpectedRange@0 @@ -1796,6 +1768,8 @@ _KiEndUnexpectedRange@0: jmp _KiUnexpectedInterruptTail .func KiUnexpectedInterruptTail +V86_kui: V86_TRAP_FIXUP +Dr_kui: DR_TRAP_FIXUP _KiUnexpectedInterruptTail: /* Enter interrupt trap */ @@ -1907,6 +1881,8 @@ QuantumEnd: .endfunc .func KiInterruptTemplate +V86_kit: V86_TRAP_FIXUP +Dr_kit: DR_TRAP_FIXUP _KiInterruptTemplate: /* Enter interrupt trap */