Ring3: Saved ReturnSP on SysCallStack.

This commit is contained in:
Mikhail Krichanov 2025-01-20 19:45:00 +03:00
parent a37ef161b6
commit 213713f790
14 changed files with 69 additions and 88 deletions

View File

@ -12,9 +12,7 @@
typedef typedef
EFI_STATUS EFI_STATUS
(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( (EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)(
IN UINT8 Type, IN EFI_SYSTEM_CONTEXT Context
IN VOID *CoreRbp,
IN VOID *UserRsp
); );
/** /**

View File

@ -44,7 +44,7 @@ This is the stack constructed by the exception handler (low address to high addr
LR 0x54 # SVC Link register (we need to restore it) LR 0x54 # SVC Link register (we need to restore it)
TTBR0 0x58 TTBR0 0x58
Padding 0x5c SP_EL1 0x5c
LR 0x60 # pushed by srsfd LR 0x60 # pushed by srsfd
CPSR 0x64 CPSR 0x64
@ -101,7 +101,7 @@ ASM_PFX(Fiq):
ASM_PFX(ResetEntry): ASM_PFX(ResetEntry):
srsdb #0x13! @ Store return state on SVC stack srsdb #0x13! @ Store return state on SVC stack
@ We are already in SVC mode @ We are already in SVC mode
sub SP, SP, #0x8 @ Save space for TTBR0 sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1
stmfd SP!,{LR} @ Store the link register for the current mode stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state stmfd SP!,{R0-R12} @ Store the register state
@ -114,7 +114,7 @@ ASM_PFX(UndefinedInstructionEntry):
sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
srsdb #0x13! @ Store return state on SVC stack srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0 sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1
stmfd SP!,{LR} @ Store the link register for the current mode stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state stmfd SP!,{R0-R12} @ Store the register state
@ -128,7 +128,7 @@ ASM_PFX(SoftwareInterruptEntry):
isb isb
srsdb #0x13! @ Store return state on SVC stack srsdb #0x13! @ Store return state on SVC stack
@ We are already in SVC mode @ We are already in SVC mode
sub SP, SP, #0x8 @ Save space for TTBR0 sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1
stmfd SP!,{LR} @ Store the link register for the current mode stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state stmfd SP!,{R0-R12} @ Store the register state
@ -141,7 +141,7 @@ ASM_PFX(PrefetchAbortEntry):
sub LR,LR,#4 sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0 sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1
stmfd SP!,{LR} @ Store the link register for the current mode stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state stmfd SP!,{R0-R12} @ Store the register state
@ -154,7 +154,7 @@ ASM_PFX(DataAbortEntry):
sub LR,LR,#8 sub LR,LR,#8
srsdb #0x13! @ Store return state on SVC stack srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0 sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1
stmfd SP!,{LR} @ Store the link register for the current mode stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state stmfd SP!,{R0-R12} @ Store the register state
@ -166,7 +166,7 @@ ASM_PFX(DataAbortEntry):
ASM_PFX(ReservedExceptionEntry): ASM_PFX(ReservedExceptionEntry):
srsdb #0x13! @ Store return state on SVC stack srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0 sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1
stmfd SP!,{LR} @ Store the link register for the current mode stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state stmfd SP!,{R0-R12} @ Store the register state
@ -179,7 +179,7 @@ ASM_PFX(IrqEntry):
sub LR,LR,#4 sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0 sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1
stmfd SP!,{LR} @ Store the link register for the current mode stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state stmfd SP!,{R0-R12} @ Store the register state
@ -192,7 +192,7 @@ ASM_PFX(FiqEntry):
sub LR,LR,#4 sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0 sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1
stmfd SP!,{LR} @ Store the link register for the current mode stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state stmfd SP!,{R0-R12} @ Store the register state
@ -242,6 +242,8 @@ ASM_PFX(AsmCommonExceptionEntry):
addne R1, SP, #0x68 @ We pushed 0x68 bytes on the stack addne R1, SP, #0x68 @ We pushed 0x68 bytes on the stack
strne R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP strne R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
add R1, SP, #0x68 @ We pushed 0x68 bytes on the stack
str R1, [SP, #0x5c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP_EL1
ldr R5, [SP, #0x60] @ PC is the LR pushed by srsfd ldr R5, [SP, #0x60] @ PC is the LR pushed by srsfd
@ Check to see if we have to adjust for Thumb entry @ Check to see if we have to adjust for Thumb entry
@ -334,7 +336,7 @@ NoTTBR0Switch2:
add SP,SP,#0x20 @ Clear out the remaining stack space add SP,SP,#0x20 @ Clear out the remaining stack space
ldmfd SP!,{LR} @ restore the link register for this context ldmfd SP!,{LR} @ restore the link register for this context
add SP, SP, #0x8 @ Clear out TTBR0 and Padding add SP, SP, #0x8 @ Clear out TTBR0 and SP_EL1
rfefd SP! @ return from exception via srsfd stack slot rfefd SP! @ return from exception via srsfd stack slot
ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096) ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096)

View File

@ -210,11 +210,7 @@ DefaultExceptionHandler (
INT32 Offset; INT32 Offset;
if (AARCH64_ESR_EC (SystemContext.SystemContextAArch64->ESR) == AARCH64_ESR_EC_SVC64) { if (AARCH64_ESR_EC (SystemContext.SystemContextAArch64->ESR) == AARCH64_ESR_EC_SVC64) {
return mSysCallHandler ( return mSysCallHandler (SystemContext);
SystemContext.SystemContextAArch64->X0,
&(SystemContext.SystemContextAArch64->X1),
&(SystemContext.SystemContextAArch64->X0)
);
} }
if (mRecursiveException) { if (mRecursiveException) {

View File

@ -222,11 +222,7 @@ DefaultExceptionHandler (
BOOLEAN DfsrWrite; BOOLEAN DfsrWrite;
if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) { if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) {
return mSysCallHandler ( return mSysCallHandler (SystemContext);
SystemContext.SystemContextArm->R0,
&(SystemContext.SystemContextArm->R1),
(VOID *)SystemContext.SystemContextArm->SP
);
} }
CharCount = AsciiSPrint ( CharCount = AsciiSPrint (

View File

@ -241,7 +241,6 @@ typedef struct {
UINTN UserPageTable; UINTN UserPageTable;
UINTN UserStackTop; UINTN UserStackTop;
UINTN SysCallStackTop; UINTN SysCallStackTop;
UINTN ReturnSP;
LIST_ENTRY Link; LIST_ENTRY Link;
} USER_SPACE_DRIVER; } USER_SPACE_DRIVER;
@ -2750,7 +2749,8 @@ EFI_STATUS
EFIAPI EFIAPI
CallBootService ( CallBootService (
IN UINT8 Type, IN UINT8 Type,
IN UINTN *UserArguments IN UINTN *UserArguments,
IN UINTN ReturnSP
); );
VOID VOID

View File

@ -62,16 +62,14 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// CallRing3 ( // CallRing3 (
// IN RING3_CALL_DATA *Data, // IN RING3_CALL_DATA *Data,
// IN UINTN UserStackTop, // IN UINTN UserStackTop,
// IN UINTN SysCallStackTop, // IN UINTN SysCallStackTop
// IN UINTN *ReturnSP
// ); // );
// //
// (x0) Data // (x0) Data
// (x1) UserStackTop // (x1) UserStackTop
// (x2) gRing3EntryPoint // (x2) gRing3EntryPoint
// (x3) SysCallStackTop // (x3) SysCallStackTop
// (x4) ReturnSP // (x4) gUserPageTable
// (x5) gUserPageTable
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3) ASM_FUNC(ArmCallRing3)
// Save registers. // Save registers.
@ -94,10 +92,10 @@ ASM_FUNC(ArmCallRing3)
// Disable interrupts. // Disable interrupts.
msr daifset, #0xf msr daifset, #0xf
isb isb
// Save Core SP and switch to SysCallStackTop. // Switch to SysCallStackTop and save ReturnSP on it.
mov x6, sp mov x6, sp
str x6, [x4]
mov sp, x3 mov sp, x3
stp x6, xzr, [sp, #-0x10]!
// Copy PSTATE to SPSR. // Copy PSTATE to SPSR.
mrs x6, nzcv mrs x6, nzcv
mrs x7, pan mrs x7, pan
@ -107,12 +105,12 @@ ASM_FUNC(ArmCallRing3)
EL1_OR_EL2(x1) EL1_OR_EL2(x1)
1:msr elr_el1, x2 1:msr elr_el1, x2
msr spsr_el1, x6 msr spsr_el1, x6
msr ttbr0_el1, x5 msr ttbr0_el1, x4
tlbi vmalle1 tlbi vmalle1
b 3f b 3f
2:msr elr_el2, x2 2:msr elr_el2, x2
msr spsr_el2, x6 msr spsr_el2, x6
msr ttbr0_el2, x5 msr ttbr0_el2, x4
tlbi alle2 tlbi alle2
3:dsb sy 3:dsb sy
isb isb

View File

@ -21,7 +21,6 @@ ArmCallRing3 (
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN UINTN SysCallStackTop, IN UINTN SysCallStackTop,
IN UINTN *ReturnSP,
IN UINTN UserPageTable IN UINTN UserPageTable
); );
@ -29,9 +28,7 @@ STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
SysCallBootService ( SysCallBootService (
IN UINT8 Type, IN EFI_SYSTEM_CONTEXT Context
IN VOID *CoreRbp,
IN VOID *UserRsp
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -42,7 +39,7 @@ SysCallBootService (
Status = CoreAllocatePages ( Status = CoreAllocatePages (
AllocateAnyPages, AllocateAnyPages,
EfiRing3MemoryType, EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)),
&Physical &Physical
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -50,12 +47,13 @@ SysCallBootService (
} }
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); CopyMem ((VOID *)Physical, (VOID *)&(Context.SystemContextAArch64->X0), 8 * sizeof (UINTN));
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
Status = CallBootService ( Status = CallBootService (
Type, Context.SystemContextAArch64->X0,
(UINTN *)((UINTN)Physical + sizeof (UINTN)) (UINTN *)Physical,
*(UINTN *)Context.SystemContextAArch64->SP
); );
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)));
@ -151,8 +149,7 @@ EFIAPI
CallRing3 ( CallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN UINTN SysCallStackTop, IN UINTN SysCallStackTop
IN UINTN *ReturnSP
) )
{ {
return ArmCallRing3 ( return ArmCallRing3 (
@ -160,7 +157,6 @@ CallRing3 (
UserStackTop, UserStackTop,
gRing3EntryPoint, gRing3EntryPoint,
SysCallStackTop, SysCallStackTop,
ReturnSP,
gUserPageTable gUserPageTable
); );
} }

View File

@ -58,8 +58,7 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// CallRing3 ( // CallRing3 (
// IN RING3_CALL_DATA *Data, // IN RING3_CALL_DATA *Data,
// IN UINTN UserStackTop, // IN UINTN UserStackTop,
// IN UINTN SysCallStackTop, // IN UINTN SysCallStackTop
// IN UINTN *ReturnSP
// ); // );
// //
// (r0) Data // (r0) Data
@ -67,15 +66,13 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// (r2) gRing3EntryPoint // (r2) gRing3EntryPoint
// (r3) SysCallStackTop // (r3) SysCallStackTop
// //
// (On Core Stack) ReturnSP, gUserPageTable // (On Core Stack) gUserPageTable
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3) ASM_FUNC(ArmCallRing3)
// Save registers. // Save registers.
push {R4-R12, LR} push {R4-R12, LR}
// R6 is ReturnSP
ldr R6, [SP, #0x28]
// R7 is gUserPageTable // R7 is gUserPageTable
ldr R7, [SP, #0x2C] ldr R7, [SP, #0x28]
// Save old SP_usr and LR_usr on Core Stack. // Save old SP_usr and LR_usr on Core Stack.
sub SP, SP, #0x8 sub SP, SP, #0x8
stmia SP, {SP, LR}^ stmia SP, {SP, LR}^
@ -98,10 +95,11 @@ ASM_FUNC(ArmCallRing3)
// Set SPSR M[3:0] bits to User mode. // Set SPSR M[3:0] bits to User mode.
and R4, R4, #0xFFFFFFF0 and R4, R4, #0xFFFFFFF0
// Save Core SP and switch to SysCallStackTop. // Switch to SysCallStackTop and save ReturnSP on it.
mov R5, SP mov R5, SP
str R5, [R6]
mov SP, R3 mov SP, R3
push {R5}
push {R5} // Align stack on 8 bytes
// Switch to UserPageTable. // Switch to UserPageTable.
mrc p15,0,R8,c2,c0,0 // R8 == TTBR0 mrc p15,0,R8,c2,c0,0 // R8 == TTBR0
@ -115,7 +113,7 @@ ASM_FUNC(ArmCallRing3)
push {R4} push {R4}
push {R2} push {R2}
rfefd SP rfefd SP!
ASM_FUNC_ALIGN(SysCallEnd, 4096) ASM_FUNC_ALIGN(SysCallEnd, 4096)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -20,7 +20,6 @@ ArmCallRing3 (
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN UINTN SysCallStackTop, IN UINTN SysCallStackTop,
IN UINTN *ReturnSP,
IN UINTN UserPageTable IN UINTN UserPageTable
); );
@ -28,9 +27,7 @@ STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
SysCallBootService ( SysCallBootService (
IN UINT8 Type, IN EFI_SYSTEM_CONTEXT Context
IN VOID *CoreRbp,
IN VOID *UserRsp
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -41,7 +38,7 @@ SysCallBootService (
Status = CoreAllocatePages ( Status = CoreAllocatePages (
AllocateAnyPages, AllocateAnyPages,
EfiRing3MemoryType, EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)),
&Physical &Physical
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -52,16 +49,17 @@ SysCallBootService (
// //
// First 3 arguments are passed through R1-R3 and copied to SysCall Stack. // First 3 arguments are passed through R1-R3 and copied to SysCall Stack.
// //
CopyMem ((VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R0), 4 * sizeof (UINTN));
// //
// All remaining arguments are on User Stack. // All remaining arguments are on User Stack.
// //
CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); CopyMem ((VOID *)((UINTN)Physical + 4 * sizeof (UINTN)), (VOID *)Context.SystemContextArm->SP, 4 * sizeof (UINTN));
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
Status = CallBootService ( Status = CallBootService (
Type, Context.SystemContextArm->R0,
(UINTN *)((UINTN)Physical + sizeof (UINTN)) (UINTN *)(UINTN)Physical,
*(UINTN *)Context.SystemContextArm->SP_EL1
); );
// //
// TODO: Fix memory leak for ReturnToCore(). // TODO: Fix memory leak for ReturnToCore().
@ -146,8 +144,7 @@ EFIAPI
CallRing3 ( CallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN UINTN SysCallStackTop, IN UINTN SysCallStackTop
IN UINTN *ReturnSP
) )
{ {
return ArmCallRing3 ( return ArmCallRing3 (
@ -155,7 +152,6 @@ CallRing3 (
UserStackTop, UserStackTop,
gRing3EntryPoint, gRing3EntryPoint,
SysCallStackTop, SysCallStackTop,
ReturnSP,
gUserPageTable gUserPageTable
); );
} }

View File

@ -318,7 +318,7 @@ FindUserInfo (
for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) { for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) {
UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link);
if ((UserDriver->UserPageTable == gUserPageTable) && (UserDriver->ReturnSP != 0)) { if (UserDriver->UserPageTable == gUserPageTable) {
return UserDriver; return UserDriver;
} }
} }
@ -330,7 +330,8 @@ EFI_STATUS
EFIAPI EFIAPI
CallBootService ( CallBootService (
IN UINT8 Type, IN UINT8 Type,
IN UINTN *UserArguments IN UINTN *UserArguments,
IN UINTN ReturnSP
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -372,10 +373,8 @@ CallBootService (
switch (Type) { switch (Type) {
case SysCallReturnToCore: case SysCallReturnToCore:
Arguments = CopyUserArguments (1, UserArguments); Arguments = CopyUserArguments (1, UserArguments);
UserDriver = FindUserInfo ();
ASSERT (UserDriver != NULL);
ReturnToCore (Arguments[1], UserDriver->ReturnSP); ReturnToCore (Arguments[1], ReturnSP);
break; break;
case SysCallLocateProtocol: case SysCallLocateProtocol:
// //
@ -531,7 +530,6 @@ CallBootService (
NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->UserStackTop = UserDriver->UserStackTop;
NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; NewDriver->SysCallStackTop = UserDriver->SysCallStackTop;
NewDriver->ReturnSP = 0;
InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link);

View File

@ -133,6 +133,8 @@ ASM_PFX(CoreBootServices):
; Prepare CallBootService arguments. ; Prepare CallBootService arguments.
mov ebp, esp mov ebp, esp
mov eax, [esp + 4*3]
push eax ; ReturnSP
add edx, 4 ; User Arguments[] add edx, 4 ; User Arguments[]
push edx push edx
push ecx ; Type push ecx ; Type
@ -166,11 +168,10 @@ ASM_PFX(CoreBootServices):
; CallRing3 ( ; CallRing3 (
; IN RING3_CALL_DATA *Data, ; IN RING3_CALL_DATA *Data,
; IN UINTN UserStackTop, ; IN UINTN UserStackTop,
; IN UINTN SysCallStackTop, ; IN UINTN SysCallStackTop
; IN UINTN *ReturnSP
; ); ; );
; ;
; (On User Stack) Data, UserStackTop, SysCallStackTop, ReturnSP ; (On User Stack) Data, UserStackTop, SysCallStackTop
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
global ASM_PFX(CallRing3) global ASM_PFX(CallRing3)
ASM_PFX(CallRing3): ASM_PFX(CallRing3):
@ -186,15 +187,16 @@ ASM_PFX(CallRing3):
pop ebx pop ebx
push eax push eax
; Save Core Stack pointer. ; Set new SysCallStackTop.
mov ebx, [esp + 4 * 9] ; ReturnSP
mov [ebx], esp
mov edx, 0 mov edx, 0
mov eax, [esp + 4 * 8] ; SysCallStackTop mov eax, [esp + 4 * 8] ; SysCallStackTop
sub eax, 4
mov ecx, MSR_IA32_SYSENTER_ESP mov ecx, MSR_IA32_SYSENTER_ESP
wrmsr wrmsr
; Save ReturnSP on SysCallStack.
mov [eax], esp
SetRing3DataSegmentSelectors SetRing3DataSegmentSelectors
; Prepare SYSEXIT arguments. ; Prepare SYSEXIT arguments.

View File

@ -15,8 +15,7 @@ EFIAPI
CallRing3 ( CallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN UINTN SysCallStackTop, IN UINTN SysCallStackTop
IN UINTN *ReturnSP
); );
EFI_STATUS EFI_STATUS
@ -66,12 +65,10 @@ GoToRing3 (
Status = CallRing3 ( Status = CallRing3 (
Input, Input,
UserDriver->UserStackTop, UserDriver->UserStackTop,
UserDriver->SysCallStackTop, UserDriver->SysCallStackTop
&UserDriver->ReturnSP
); );
CoreFreePages (Ring3Pages, PagesNumber); CoreFreePages (Ring3Pages, PagesNumber);
UserDriver->ReturnSP = 0;
return Status; return Status;
} }

View File

@ -162,6 +162,8 @@ ASM_PFX(CoreBootServices):
mov rcx, r10 ; Type mov rcx, r10 ; Type
mov rdx, [rbp + 8*3] mov rdx, [rbp + 8*3]
add rdx, 8 ; User Arguments[] add rdx, 8 ; User Arguments[]
mov rax, [ASM_PFX(SysCallStackTop)]
mov r8, [rax] ; ReturnSP
sti sti
call ASM_PFX(CallBootService) call ASM_PFX(CallBootService)
@ -195,14 +197,12 @@ o64 sysret
; CallRing3 ( ; CallRing3 (
; IN RING3_CALL_DATA *Data, ; IN RING3_CALL_DATA *Data,
; IN UINTN UserStackTop, ; IN UINTN UserStackTop,
; IN UINTN SysCallStackTop, ; IN UINTN SysCallStackTop
; IN UINTN *ReturnSP
; ); ; );
; ;
; (rcx) Data ; (rcx) Data
; (rdx) UserStackTop ; (rdx) UserStackTop
; (r8) SysCallStackTop ; (r8) SysCallStackTop
; (r9) ReturnSP
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
global ASM_PFX(CallRing3) global ASM_PFX(CallRing3)
ASM_PFX(CallRing3): ASM_PFX(CallRing3):
@ -220,8 +220,9 @@ ASM_PFX(CallRing3):
push r15 push r15
push qword [ASM_PFX(SysCallStackTop)] push qword [ASM_PFX(SysCallStackTop)]
; Save Core Stack pointer. ; Save ReturnSP on SysCallStack.
mov [r9], rsp sub r8, 8
mov [r8], rsp
; Save input Arguments. ; Save input Arguments.
mov rbx, rdx mov rbx, rdx

View File

@ -507,6 +507,9 @@ typedef struct {
UINT32 DFAR; UINT32 DFAR;
UINT32 IFSR; UINT32 IFSR;
UINT32 IFAR; UINT32 IFAR;
UINT32 SVC_LR;
UINT32 TTBR0;
UINT32 SP_EL1;
} EFI_SYSTEM_CONTEXT_ARM; } EFI_SYSTEM_CONTEXT_ARM;
/// ///