- Some cleanups

- Add support for recovering from user-mode win32k callback fault.
- Also add support for debug register saving/reloading during user-mode callbacks and return.

svn path=/trunk/; revision=23849
This commit is contained in:
Alex Ionescu 2006-08-31 18:10:11 +00:00
parent 158e4c116a
commit 01081d279e
5 changed files with 101 additions and 51 deletions

View file

@ -430,6 +430,7 @@ Author:
#define STATUS_ACCESS_VIOLATION 0xC0000005
#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258
#define STATUS_CALLBACK_POP_STACK 0xC0000423
#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C
#define STATUS_ILLEGAL_INSTRUCTION 0xC000001D
#define STATUS_BREAKPOINT 0x80000003

View file

@ -10,23 +10,35 @@
/* GLOBALS ****************************************************************/
.globl _DbgBreakPoint@0
.globl _DbgBreakPointWithStatus@4
.globl _DbgUserBreakPoint@0
.globl _DebugService@20
.globl _DbgBreakPoint@0
.globl _DbgBreakPointWithStatus@4
.globl _DbgUserBreakPoint@0
.globl _DebugService@20
.globl _DbgBreakPointNoBugCheck@0
/* FUNCTIONS ***************************************************************/
.func DbgBreakPointNoBugCheck@0
_DbgBreakPointNoBugCheck@0:
int 3
ret
.endfunc
.func DbgBreakPoint@0
_DbgBreakPoint@0:
_DbgUserBreakPoint@0:
int 3
ret
.endfunc
.func DbgBreakPointWithStatus@4
_DbgBreakPointWithStatus@4:
mov eax, [esp+4]
int 3
ret 4
.endfunc
.func DebugService@20
_DebugService@20:
/* Setup the stack */
@ -58,4 +70,4 @@ _DebugService@20:
/* Return */
leave
ret 20
.endfunc

View file

@ -11,30 +11,19 @@
#include <asm.h>
.intel_syntax noprefix
/* GLOBALS ****************************************************************/
/* FUNCTIONS ****************************************************************/
.global _DbgBreakPointNoBugCheck@0
.func DbgBreakPointNoBugCheck@0
_DbgBreakPointNoBugCheck@0:
int 3
ret
.endfunc
.globl _KeFlushCurrentTb@0
.func KeFlushCurrentTb@0
_KeFlushCurrentTb@0:
/* Check for global page support */
test byte ptr [_Ke386GlobalPagesEnabled], 0xff
jz .L1
/* Modifying the PSE, PGE or PAE Flag in CR4 causes the TLB to be flushed */
mov eax, cr4
.att_syntax /* Older binutils versions don't support ~ for .intel_syntax */
and $~CR4_PGE, %eax
.intel_syntax noprefix
and eax, ~CR4_PGE
mov cr4, eax
or eax, CR4_PGE
mov cr4, eax
@ -47,25 +36,4 @@ _KeFlushCurrentTb@0:
ret
.endfunc
.globl _KiCoprocessorError@0
.func KiCoprocessorError@0
_KiCoprocessorError@0:
/* Get the NPX Thread's Initial stack */
mov eax, [fs:KPCR_NPX_THREAD]
mov eax, [eax+KTHREAD_INITIAL_STACK]
/* Make space for the FPU Save area */
sub eax, SIZEOF_FX_SAVE_AREA
/* Set the CR0 State */
mov dword ptr [eax+FN_CR0_NPX_STATE], 8
/* Update it */
mov eax, cr0
or eax, 8
mov cr0, eax
/* Return to caller */
ret
.endfunc

View file

@ -55,6 +55,7 @@ GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */
/* And special system-defined software traps: */
.globl _NtRaiseException@12
.globl _NtContinue@8
.globl _KiCoprocessorError@0
/* Interrupt template entrypoints */
.globl _KiInterruptTemplate
@ -1472,6 +1473,28 @@ _KiSystemFatalException:
ret
.endfunc
.func KiCoprocessorError@0
_KiCoprocessorError@0:
/* Get the NPX Thread's Initial stack */
mov eax, [fs:KPCR_NPX_THREAD]
mov eax, [eax+KTHREAD_INITIAL_STACK]
/* Make space for the FPU Save area */
sub eax, SIZEOF_FX_SAVE_AREA
/* Set the CR0 State */
mov dword ptr [eax+FN_CR0_NPX_STATE], 8
/* Update it */
mov eax, cr0
or eax, 8
mov cr0, eax
/* Return to caller */
ret
.endfunc
/* UNEXPECTED INTERRUPT HANDLERS **********************************************/
.globl _KiStartUnexpectedRange@0

View file

@ -127,9 +127,7 @@ StackOk:
mov [ebx+KTHREAD_CALLBACK_STACK], esp
/* Align stack on 16-byte boundary */
.att_syntax /* Older binutils versions don't support ~ for intel_syntax */
and $~15,%esp
.intel_syntax noprefix
and esp, ~15
mov edi, esp
/* Set destination and origin NPX Areas */
@ -178,13 +176,16 @@ DontBias:
lea esi, [edx+KTRAP_FRAME_FS]
rep movsd
/* VMWARE Hack because ES/DS sometimes gets smashed when returning to User-Mode. Investigate! */
mov dword ptr [esp+KTRAP_FRAME_DS], KGDT_R3_DATA + RPL_MASK
mov dword ptr [esp+KTRAP_FRAME_ES], KGDT_R3_DATA + RPL_MASK
/* Copy DR7 */
mov edi, [edx+KTRAP_FRAME_DR7]
test edi, ~DR7_RESERVED_MASK
mov [esp+KTRAP_FRAME_DR7], edi
/* FIXME: Copy debug registers if needed */
/* Check if we need to save debug registers */
jnz SaveDebug
/* Get user-mode dispatcher address and set it as EIP */
SetEip:
mov eax, _KeUserCallbackDispatcher
mov [esp+KTRAP_FRAME_EIP], eax
@ -205,6 +206,15 @@ DontBias:
/* Exit to user-mode */
jmp _KiServiceExit
SaveDebug:
/* Copy all 5 DRs */
mov ecx, 5
lea edi, [esp+KTRAP_FRAME_DR0]
lea esi, [edx+KTRAP_FRAME_DR0]
rep movsd
jmp SetEip
GrowFailed:
/* Restore registers */
pop edi
@ -294,11 +304,19 @@ _NtCallbackReturn@12:
mov edx, [esi+FN_CR0_NPX_STATE]
mov [ebx+FN_CR0_NPX_STATE], edx
/* Get saved trap frame and clear DR7 */
/* Check if we failed in user mode */
cmp ebp, STATUS_CALLBACK_POP_STACK
mov edi, [ecx+CBSTACK_TRAP_FRAME]
jz UserFault
CheckDebug:
/* Clear DR7 */
and dword ptr [edi+KTRAP_FRAME_DR7], 0
/* FIXME: Restore debug regs */
/* Check if debugging was active */
test byte ptr [eax+KTHREAD_DEBUG_ACTIVE], 0xFF
jnz RestoreDebug
/* Get TSS */
mov edx, fs:[KPCR_TSS]
@ -336,12 +354,41 @@ V86Ret:
add esp, 8
jmp edx
UserFault:
/* Set size to copy */
mov ecx, (KTRAP_FRAME_V86_ES - KTRAP_FRAME_FS) / 4
/* Check if this was V86 mode */
mov esi, [eax+KTHREAD_TRAP_FRAME]
test dword ptr [esi+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
/* Save EDI and load destination */
mov edx, edi
lea edi, [edi+KTRAP_FRAME_FS]
jz NotV86
add ecx, 16 / 4
NotV86:
/* Set source and copy */
lea esi, [esi+KTRAP_FRAME_FS]
rep movsd
/* Restore ECX and ECX */
mov ecx, [eax+KTHREAD_CALLBACK_STACK]
mov edi, edx
jmp CheckDebug
RestoreDebug:
/* Not yet supported */
int 3
jmp $
NoStack:
/* Return failure */
mov eax, STATUS_NO_CALLBACK_ACTIVE
ret 12
.endfunc
/*++
@ -450,5 +497,4 @@ V86Switch:
pop edi
pop esi
ret 8
.endfunc