Skip to content

Commit

Permalink
Ring3: Defined SysCallReturnToCore for AARCH64,
Browse files Browse the repository at this point in the history
forbade ExceptionHanlders to use EL0 stack.
  • Loading branch information
Mikhail Krichanov committed May 23, 2024
1 parent 999108e commit 2416073
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 31 deletions.
27 changes: 3 additions & 24 deletions ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,7 @@ ASM_PFX(ExceptionHandlersStart):
VECTOR_BASE(ExceptionHandlersStart)
#endif

.macro ExceptionEntry, val, sp=SPx
//
// 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

.macro ExceptionEntry, val
// Move the stackpointer so we can reach our structure with the str instruction.
sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)

Expand All @@ -154,13 +138,7 @@ VECTOR_BASE(ExceptionHandlersStart)
stp x28, x29, [sp, #0xe0]
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
.endif

stp x30, x7, [sp, #0xf0]

Expand Down Expand Up @@ -201,7 +179,7 @@ ASM_PFX(SErrorSP0):
//
VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPX_SYNC)
ASM_PFX(SynchronousExceptionSPx):
ExceptionEntry EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, SP0
ExceptionEntry EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS

VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPX_IRQ)
ASM_PFX(IrqSPx):
Expand Down Expand Up @@ -343,6 +321,7 @@ ASM_PFX(CommonExceptionEntry):
b continue
is_SVC:
ldr x1, [sp, #0x8]
add sp, sp, #0xe0
continue:

// Pop FP regs from Stack.
Expand Down
30 changes: 25 additions & 5 deletions MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,22 @@ ASM_FUNC(CallInstallMultipleProtocolInterfaces)
// (x0) Data
// (x1) gRing3CallStackTop
// (x2) gRing3EntryPoint
// (x3) gCoreSysCallStackTop
// (x4) &CoreSp
//------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3)
// Save FP and LR on Core Stack.
stp x29, x30, [sp, #-0x10]!
// Disable interrupts
msr daifset, #0xf
isb

// Use SP_ELx for Exception level ELx.
msr SPsel, #1

// Prepare Ring3 SP and EntryPoint.
msr sp_el0, x1

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.
mrs x1, nzcv
Expand All @@ -61,3 +65,19 @@ ASM_FUNC(ArmCallRing3)
dsb sy

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
8 changes: 6 additions & 2 deletions MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@

#include "DxeMain.h"

extern UINTN CoreSp;

EFI_STATUS
EFIAPI
ArmCallRing3 (
IN RING3_CALL_DATA *Data,
IN VOID *StackPointer,
IN VOID *EntryPoint
IN VOID *EntryPoint,
IN VOID *SysCallStack,
IN VOID *CoreStack
);

VOID
Expand Down Expand Up @@ -74,5 +78,5 @@ CallRing3 (
IN RING3_CALL_DATA *Data
)
{
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint);
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &CoreSp);
}
13 changes: 13 additions & 0 deletions MdeModulePkg/Core/Dxe/SysCall/BootServices.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "DxeMain.h"
#include "SupportedProtocols.h"

UINTN CoreSp;

LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead);

typedef struct {
Expand Down Expand Up @@ -65,6 +67,13 @@ CallInstallMultipleProtocolInterfaces (
IN VOID *Function
);

VOID
EFIAPI
ReturnToCore (
IN EFI_STATUS Status,
IN UINTN CoreSp
);

VOID
EFIAPI
FreeProtocolsList (
Expand Down Expand Up @@ -1403,6 +1412,10 @@ SysCallBootService (
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical;

if (Type == SysCallReturnToCore) {
ReturnToCore (*(EFI_STATUS *)CoreRbp, CoreSp);
}

Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
Expand Down

0 comments on commit 2416073

Please sign in to comment.