mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[NTOS:KE/x64] Fix handling of non-volatiles in trap vs exception frame
The registers that are saved/restored in the trap / exception frame need to be consistent between all entry/exit points as well as the functions that convert between trap/exception frame and context. The trap frame contains only the non-volatile registers and rbp, the rest is saved in the exception frame. The previous code didn't save rbp in the syscall handler, which led to it being clobbered when exiting though KiServiceExit2 rather than returning back to the syscall exit path. Also KeContextToTrapFrame would use rbx, rsi and rdi from the trap frame, which wouldn't be saved there by the syscall handler.
This commit is contained in:
parent
83e741c643
commit
05456808e8
3 changed files with 6 additions and 21 deletions
|
@ -36,11 +36,8 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
if (ContextFlags & CONTEXT_INTEGER)
|
||||
{
|
||||
TrapFrame->Rax = Context->Rax;
|
||||
TrapFrame->Rbx = Context->Rbx;
|
||||
TrapFrame->Rcx = Context->Rcx;
|
||||
TrapFrame->Rdx = Context->Rdx;
|
||||
TrapFrame->Rsi = Context->Rsi;
|
||||
TrapFrame->Rdi = Context->Rdi;
|
||||
TrapFrame->Rbp = Context->Rbp;
|
||||
TrapFrame->R8 = Context->R8;
|
||||
TrapFrame->R9 = Context->R9;
|
||||
|
@ -48,6 +45,9 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
TrapFrame->R11 = Context->R11;
|
||||
if (ExceptionFrame)
|
||||
{
|
||||
ExceptionFrame->Rbx = Context->Rbx;
|
||||
ExceptionFrame->Rsi = Context->Rsi;
|
||||
ExceptionFrame->Rdi = Context->Rdi;
|
||||
ExceptionFrame->R12 = Context->R12;
|
||||
ExceptionFrame->R13 = Context->R13;
|
||||
ExceptionFrame->R14 = Context->R14;
|
||||
|
|
|
@ -781,6 +781,7 @@ PUBLIC KiSystemCallEntry64
|
|||
/* The unwind info pretends we have a machine frame */
|
||||
.PUSHFRAME
|
||||
.ALLOCSTACK (KTRAP_FRAME_LENGTH + MAX_SYSCALL_PARAM_SIZE - MachineFrameLength)
|
||||
.SAVEREG rbp, MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rbp
|
||||
.ENDPROLOG
|
||||
|
||||
/* Swap gs to kernel, so we can access the PCR */
|
||||
|
@ -795,7 +796,7 @@ PUBLIC KiSystemCallEntry64
|
|||
/* Allocate a TRAP_FRAME and space for parameters */
|
||||
sub rsp, (KTRAP_FRAME_LENGTH + MAX_SYSCALL_PARAM_SIZE)
|
||||
|
||||
/* Save volatile registers in the trap frame */
|
||||
/* Save volatile registers and rbp in the trap frame */
|
||||
mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rax], rax
|
||||
mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rip], rcx
|
||||
mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rdx], rdx
|
||||
|
@ -803,6 +804,7 @@ PUBLIC KiSystemCallEntry64
|
|||
mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R9], r9
|
||||
mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rcx], r10
|
||||
mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_EFlags], r11
|
||||
mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rbp], rbp
|
||||
|
||||
/* Store user stack pointer in the trap frame */
|
||||
mov rax, gs:[PcUserRsp]
|
||||
|
|
|
@ -108,16 +108,6 @@ MACRO(EnterTrap, Flags)
|
|||
lea rbp, [rsp]
|
||||
.setframe rbp, 0
|
||||
|
||||
if (Flags AND TF_NONVOLATILES)
|
||||
/* Save non-volatile registers */
|
||||
mov [rbp + KTRAP_FRAME_Rbx], rbx
|
||||
.savereg rbx, KTRAP_FRAME_Rbx
|
||||
mov [rbp + KTRAP_FRAME_Rdi], rdi
|
||||
.savereg rdi, KTRAP_FRAME_Rdi
|
||||
mov [rbp + KTRAP_FRAME_Rsi], rsi
|
||||
.savereg rsi, KTRAP_FRAME_Rsi
|
||||
endif
|
||||
|
||||
.endprolog
|
||||
|
||||
if (Flags AND TF_VOLATILES)
|
||||
|
@ -243,13 +233,6 @@ MACRO(ExitTrap, Flags)
|
|||
|
||||
kernel_mode_return:
|
||||
|
||||
if (Flags AND TF_NONVOLATILES)
|
||||
/* Restore non-volatile registers */
|
||||
mov rbx, [rbp + KTRAP_FRAME_Rbx]
|
||||
mov rdi, [rbp + KTRAP_FRAME_Rdi]
|
||||
mov rsi, [rbp + KTRAP_FRAME_Rsi]
|
||||
endif
|
||||
|
||||
if (Flags AND TF_VOLATILES)
|
||||
/* Restore volatile registers */
|
||||
mov rax, [rbp + KTRAP_FRAME_Rax]
|
||||
|
|
Loading…
Reference in a new issue