Ring3: Defined SysCallReturnToCore for AARCH64,

forbade ExceptionHanlders to use EL0 stack.
This commit is contained in:
Mikhail Krichanov 2024-05-23 20:46:54 +03:00
parent c542f9f3b0
commit c5d244956e
4 changed files with 47 additions and 31 deletions

View File

@ -116,23 +116,7 @@ ASM_PFX(ExceptionHandlersStart):
VECTOR_BASE(ExceptionHandlersStart) VECTOR_BASE(ExceptionHandlersStart)
#endif #endif
.macro ExceptionEntry, val, sp=SPx .macro ExceptionEntry, val
//
// Our backtrace and register dump code is written in C and so it requires
// a stack. This makes it difficult to produce meaningful diagnostics when
// the stack pointer has been corrupted. So in such cases (i.e., when taking
// synchronous exceptions), this macro is expanded with \sp set to SP0, in
// which case we switch to the SP_EL0 stack pointer, which has been
// initialized to point to a buffer that has been set aside for this purpose.
//
// Since 'sp' may no longer refer to the stack frame that was active when
// the exception was taken, we may have to switch back and forth between
// SP_EL0 and SP_ELx to record the correct value for SP in the context struct.
//
.ifnc \sp, SPx
msr SPsel, xzr
.endif
// Move the stackpointer so we can reach our structure with the str instruction. // Move the stackpointer so we can reach our structure with the str instruction.
sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
@ -154,13 +138,7 @@ VECTOR_BASE(ExceptionHandlersStart)
stp x28, x29, [sp, #0xe0] stp x28, x29, [sp, #0xe0]
add x28, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) add x28, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
.ifnc \sp, SPx
msr SPsel, #1
mov x7, sp
msr SPsel, xzr
.else
mov x7, x28 mov x7, x28
.endif
stp x30, x7, [sp, #0xf0] stp x30, x7, [sp, #0xf0]
@ -201,7 +179,7 @@ ASM_PFX(SErrorSP0):
// //
VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPX_SYNC) VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPX_SYNC)
ASM_PFX(SynchronousExceptionSPx): ASM_PFX(SynchronousExceptionSPx):
ExceptionEntry EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, SP0 ExceptionEntry EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS
VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPX_IRQ) VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPX_IRQ)
ASM_PFX(IrqSPx): ASM_PFX(IrqSPx):
@ -343,6 +321,7 @@ ASM_PFX(CommonExceptionEntry):
b continue b continue
is_SVC: is_SVC:
ldr x1, [sp, #0x8] ldr x1, [sp, #0x8]
add sp, sp, #0xe0
continue: continue:
// Pop FP regs from Stack. // Pop FP regs from Stack.

View File

@ -30,18 +30,22 @@ ASM_FUNC(CallInstallMultipleProtocolInterfaces)
// (x0) Data // (x0) Data
// (x1) gRing3CallStackTop // (x1) gRing3CallStackTop
// (x2) gRing3EntryPoint // (x2) gRing3EntryPoint
// (x3) gCoreSysCallStackTop
// (x4) &CoreSp
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3) ASM_FUNC(ArmCallRing3)
// Save FP and LR on Core Stack.
stp x29, x30, [sp, #-0x10]!
// Disable interrupts // Disable interrupts
msr daifset, #0xf msr daifset, #0xf
isb isb
// Prepare Ring3 SP and EntryPoint.
// Use SP_ELx for Exception level ELx.
msr SPsel, #1
msr sp_el0, x1 msr sp_el0, x1
msr elr_el1, x2 msr elr_el1, x2
// Save Core SP and switch to Ring3Call Stack.
mov x5, sp
str x5, [x4]
mov sp, x3
// Copy PSTATE to SPSR. // Copy PSTATE to SPSR.
mrs x1, nzcv mrs x1, nzcv
@ -61,3 +65,19 @@ ASM_FUNC(ArmCallRing3)
dsb sy dsb sy
eret eret
//------------------------------------------------------------------------------
// VOID
// EFIAPI
// ReturnToCore (
// IN EFI_STATUS Status,
// IN UINTN CoreSp
// );
//------------------------------------------------------------------------------
ASM_FUNC(ReturnToCore)
// Switch to Core Stack.
mov sp, x1
// Restore Stack.
ldp x29, x30, [sp]
add sp, sp, #0x10
ret

View File

@ -10,12 +10,16 @@
#include "DxeMain.h" #include "DxeMain.h"
extern UINTN CoreSp;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
ArmCallRing3 ( ArmCallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN VOID *StackPointer, IN VOID *StackPointer,
IN VOID *EntryPoint IN VOID *EntryPoint,
IN VOID *SysCallStack,
IN VOID *CoreStack
); );
VOID VOID
@ -74,5 +78,5 @@ CallRing3 (
IN RING3_CALL_DATA *Data IN RING3_CALL_DATA *Data
) )
{ {
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint); return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &CoreSp);
} }

View File

@ -8,6 +8,8 @@
#include "DxeMain.h" #include "DxeMain.h"
#include "SupportedProtocols.h" #include "SupportedProtocols.h"
UINTN CoreSp;
LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead);
typedef struct { typedef struct {
@ -65,6 +67,13 @@ CallInstallMultipleProtocolInterfaces (
IN VOID *Function IN VOID *Function
); );
VOID
EFIAPI
ReturnToCore (
IN EFI_STATUS Status,
IN UINTN CoreSp
);
VOID VOID
EFIAPI EFIAPI
FreeProtocolsList ( FreeProtocolsList (
@ -1403,6 +1412,10 @@ SysCallBootService (
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical; EFI_PHYSICAL_ADDRESS Physical;
if (Type == SysCallReturnToCore) {
ReturnToCore (*(EFI_STATUS *)CoreRbp, CoreSp);
}
Status = CoreAllocatePages ( Status = CoreAllocatePages (
AllocateAnyPages, AllocateAnyPages,
EfiRing3MemoryType, EfiRing3MemoryType,