Implement KiServiceExit2 which restores debug registers and exits with
IRET, used during user-mode return without a syscall
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
--- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2005-04-23 04:31:11 UTC
(rev 14757)
+++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2005-04-23 05:00:10 UTC
(rev 14758)
@@ -88,7 +88,7 @@
mov ebp, esp
/* Exit back to user-mode */
- jmp _KiServiceExit
+ jmp _KiServiceExit2
BadThread:
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
--- trunk/reactos/ntoskrnl/ke/i386/syscall.S 2005-04-23 04:31:11 UTC
(rev 14757)
+++ trunk/reactos/ntoskrnl/ke/i386/syscall.S 2005-04-23 05:00:10 UTC
(rev 14758)
@@ -22,6 +22,7 @@
.globl KeReturnFromSystemCallWithHook
.globl _KiServiceExit
+.globl _KiServiceExit2
.globl _KiFastCallEntry
.globl _KiSystemService
@@ -317,3 +318,82 @@
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
movl %eax, KTRAP_FRAME_EAX(%ebp)
jmp _KiServiceExit
+
+_KiServiceExit2:
+
+ /* Get the Current Thread */
+ cli
+ movl %fs:KPCR_CURRENT_THREAD, %esi
+
+ /* Deliver APCs only if we were called from user mode */
+ testb $1, KTRAP_FRAME_CS(%esp)
+ je KiRosTrapReturn
+
+ /* And only if any are actually pending */
+ cmpb $0, KTHREAD_PENDING_USER_APC(%esi)
+ je KiRosTrapReturn
+
+ /* Save pointer to Trap Frame */
+ movl %esp, %ebx
+
+ /* Raise IRQL to APC_LEVEL */
+ movl $1, %ecx
+ call @KfRaiseIrql@4
+
+ /* Save old IRQL */
+ pushl %eax
+
+ /* Deliver APCs */
+ sti
+ pushl %ebx
+ pushl $0
+ pushl $UserMode
+ call _KiDeliverApc@12
+ cli
+
+ /* Return to old IRQL */
+ popl %ecx
+ call @KfLowerIrql@4
+
+ /* Skip useless Debug Data */
+ addl $0x18, %esp
// + 0x74
+
+ /* Restore Debug Registers */
+ popl %eax
// + 0x5C
+ movl %eax, %dr0
+ popl %eax
// + 0x58
+ movl %eax, %dr1
+ popl %eax
// + 0x54
+ movl %eax, %dr2
+ popl %eax
// + 0x50
+ movl %eax, %dr3
+ popl %eax
// + 0x4C
+ movl %eax, %dr6
+ popl %eax
// + 0x48
+ movl %eax, %dr7
+
+ /* Restore Registers */
+ popl %gs
// + 0x44
+ popl %es
// + 0x40
+ popl %ds
// + 0x3C
+ popl %edx
// + 0x38
+ popl %ecx
// + 0x34
+ popl %eax
// + 0x30
+
+ /* Restore the old previous mode */
+ popl %ebx
// + 0x2C
+ movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
+
+ /* Restore the old exception handler list */
+ popl %fs:KPCR_EXCEPTION_LIST
// + 0x28
+
+ /* Restore final registers from trap frame */
+ popl %fs
// + 0x24
+ popl %edi
// + 0x20
+ popl %esi
// + 0x1C
+ popl %ebx
// + 0x18
+ popl %ebp
// + 0x14
+ add $4, %esp
// + 0x10
+
+ /* Return to user-mode */
+ iret