mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 17:03:02 +00:00
[NTOS:KE/x64][SDK] Add HANDLE_USER_APCS asm macro
This also fixes delivering APCs from the system call handler, which previously would have clobbered rax. Also don't use the thread's TrapFrame member, which is not always set, when returning.
This commit is contained in:
parent
88e24bc463
commit
24b4026ce8
2 changed files with 33 additions and 13 deletions
|
@ -850,12 +850,9 @@ GLOBAL_LABEL KiSystemServiceExit
|
||||||
|
|
||||||
ASSERT_TRAP_FRAME_INTS_ENABLED rsp + MAX_SYSCALL_PARAM_SIZE
|
ASSERT_TRAP_FRAME_INTS_ENABLED rsp + MAX_SYSCALL_PARAM_SIZE
|
||||||
|
|
||||||
/* Check for pending user APC */
|
/* Check for pending user APCs */
|
||||||
mov rcx, gs:qword ptr [PcCurrentThread]
|
mov rcx, gs:[PcCurrentThread]
|
||||||
cmp byte ptr [rcx + ThApcState + AsUserApcPending], 0
|
HANDLE_USER_APCS rcx, rsp + MAX_SYSCALL_PARAM_SIZE
|
||||||
jz no_user_apc_pending
|
|
||||||
call KiInitiateUserApc
|
|
||||||
no_user_apc_pending:
|
|
||||||
|
|
||||||
/* Disable interrupts for return */
|
/* Disable interrupts for return */
|
||||||
cli
|
cli
|
||||||
|
@ -1137,12 +1134,23 @@ PUBLIC KiSetTrapContext
|
||||||
*/
|
*/
|
||||||
EXTERN KiDeliverApc:PROC
|
EXTERN KiDeliverApc:PROC
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VOID
|
||||||
|
* KiInitiateUserApc(
|
||||||
|
* _In_ PKTRAP_FRAME TrapFrame@<rcx>);
|
||||||
|
*
|
||||||
|
* This function is called to deliver user mode APCs.
|
||||||
|
* It clobbers all non-volatile registers, except rax.
|
||||||
|
*/
|
||||||
PUBLIC KiInitiateUserApc
|
PUBLIC KiInitiateUserApc
|
||||||
.PROC KiInitiateUserApc
|
.PROC KiInitiateUserApc
|
||||||
|
|
||||||
/* Generate a KEXCEPTION_FRAME on the stack */
|
/* Generate a KEXCEPTION_FRAME on the stack */
|
||||||
GENERATE_EXCEPTION_FRAME
|
GENERATE_EXCEPTION_FRAME
|
||||||
|
|
||||||
|
/* Save rax to not clobber the return for the system call handler */
|
||||||
|
mov [rsp + ExP1Home], rax
|
||||||
|
|
||||||
/* Raise IRQL to APC_LEVEL */
|
/* Raise IRQL to APC_LEVEL */
|
||||||
mov rax, APC_LEVEL
|
mov rax, APC_LEVEL
|
||||||
mov cr8, rax
|
mov cr8, rax
|
||||||
|
@ -1150,6 +1158,9 @@ PUBLIC KiInitiateUserApc
|
||||||
/* Get the current thread */
|
/* Get the current thread */
|
||||||
mov rbp, gs:[PcCurrentThread]
|
mov rbp, gs:[PcCurrentThread]
|
||||||
|
|
||||||
|
/* Save the trap frame in rsi */
|
||||||
|
mov rsi, rcx
|
||||||
|
|
||||||
deliver_apcs:
|
deliver_apcs:
|
||||||
|
|
||||||
/* Enable interrupts */
|
/* Enable interrupts */
|
||||||
|
@ -1158,7 +1169,7 @@ deliver_apcs:
|
||||||
/* Call the C function */
|
/* Call the C function */
|
||||||
mov ecx, 1
|
mov ecx, 1
|
||||||
mov rdx, rsp
|
mov rdx, rsp
|
||||||
mov r8, [rbp + ThTrapFrame]
|
mov r8, rsi
|
||||||
call KiDeliverApc
|
call KiDeliverApc
|
||||||
|
|
||||||
/* Disable interrupts again */
|
/* Disable interrupts again */
|
||||||
|
@ -1173,6 +1184,7 @@ deliver_apcs:
|
||||||
mov cr8, rax
|
mov cr8, rax
|
||||||
|
|
||||||
/* Restore the registers from the KEXCEPTION_FRAME */
|
/* Restore the registers from the KEXCEPTION_FRAME */
|
||||||
|
mov rax, [rsp + ExP1Home]
|
||||||
RESTORE_EXCEPTION_STATE
|
RESTORE_EXCEPTION_STATE
|
||||||
|
|
||||||
/* Return */
|
/* Return */
|
||||||
|
|
|
@ -37,6 +37,19 @@ IrqlIsPassive:
|
||||||
#endif
|
#endif
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
|
// Checks for user APCs and delivers them if necessary.
|
||||||
|
// Clobbers all volatile registers except rax.
|
||||||
|
MACRO(HANDLE_USER_APCS, ThreadReg, TrapFrame)
|
||||||
|
LOCAL NoUserApcPending
|
||||||
|
|
||||||
|
/* Check for pending user APC */
|
||||||
|
cmp byte ptr [ThreadReg + ThApcState + AsUserApcPending], 0
|
||||||
|
jz NoUserApcPending
|
||||||
|
lea rcx, [TrapFrame]
|
||||||
|
call KiInitiateUserApc
|
||||||
|
NoUserApcPending:
|
||||||
|
ENDM
|
||||||
|
|
||||||
APIC_EOI = HEX(0FFFFFFFFFFFE00B0)
|
APIC_EOI = HEX(0FFFFFFFFFFFE00B0)
|
||||||
|
|
||||||
TF_VOLATILES = HEX(01)
|
TF_VOLATILES = HEX(01)
|
||||||
|
@ -195,7 +208,6 @@ ENDM
|
||||||
*/
|
*/
|
||||||
MACRO(ExitTrap, Flags)
|
MACRO(ExitTrap, Flags)
|
||||||
LOCAL kernel_mode_return
|
LOCAL kernel_mode_return
|
||||||
LOCAL NoUserApc
|
|
||||||
|
|
||||||
ASSERT_TRAP_FRAME_IRQL_VALID rbp
|
ASSERT_TRAP_FRAME_IRQL_VALID rbp
|
||||||
|
|
||||||
|
@ -217,12 +229,8 @@ MACRO(ExitTrap, Flags)
|
||||||
jz kernel_mode_return
|
jz kernel_mode_return
|
||||||
|
|
||||||
if (Flags AND TF_CHECKUSERAPC)
|
if (Flags AND TF_CHECKUSERAPC)
|
||||||
/* Load current thread into r10 */
|
|
||||||
mov r10, gs:[PcCurrentThread]
|
mov r10, gs:[PcCurrentThread]
|
||||||
cmp byte ptr [r10 + KTHREAD_UserApcPending], 0
|
HANDLE_USER_APCS r10, rbp
|
||||||
je NoUserApc
|
|
||||||
call KiInitiateUserApc
|
|
||||||
NoUserApc:
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ASSERT_TRAP_FRAME_INTS_ENABLED rbp
|
ASSERT_TRAP_FRAME_INTS_ENABLED rbp
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue