From bdea79e171b4960ccbb1866a09ef0fe83ecca83b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 9 Jul 2024 11:40:26 +0300 Subject: [PATCH] Ring3: Defined SysCallBootService() for ARM. --- .../Library/DefaultExceptionHandlerLib.h | 10 +++- .../ArmExceptionLib/Arm/ExceptionSupport.S | 31 +++++------- .../AArch64/DefaultExceptionHandler.c | 13 ++--- .../Arm/DefaultExceptionHandler.c | 19 ++++++++ .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 20 -------- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 47 +++++++++++++++++++ 6 files changed, 90 insertions(+), 50 deletions(-) diff --git a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h index 1381cb4f6d..24893c6fa8 100644 --- a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h +++ b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h @@ -9,6 +9,14 @@ #ifndef DEFAULT_EXCEPTION_HANDLER_LIB_H_ #define DEFAULT_EXCEPTION_HANDLER_LIB_H_ +typedef +EFI_STATUS +(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ); + /** This is the default action to take on an unexpected exception @@ -26,7 +34,7 @@ DefaultExceptionHandler ( VOID EFIAPI InitializeSysCallHandler ( - IN VOID *Handler + IN EFI_SYS_CALL_BOOT_SERVICE Handler ); #endif // DEFAULT_EXCEPTION_HANDLER_LIB_H_ diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S index d9ad775934..5d2a5617f8 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S @@ -220,8 +220,12 @@ ASM_PFX(AsmCommonExceptionEntry): cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f)) cmpne R3, #0x10 @ stmdaeq R2, {lr}^ @ save unbanked lr + addeq R2, SP, #0x34 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.SP + stmdaeq R2, {sp}^ @ save unbanked sp @ else stmdane R2, {lr} @ save SVC lr + addne R1, SP, #0x60 @ We pushed 0x60 bytes on the stack + strne R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd @@ -230,6 +234,7 @@ ASM_PFX(AsmCommonExceptionEntry): cmp r4, #1 @ // UND & SVC have different LR adjust for Thumb bhi NoAdjustNeeded + ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry addne R5, R5, #2 @ PC += 2; strne R5,[SP,#0x58] @ Update LR value pushed by srsfd @@ -238,9 +243,6 @@ NoAdjustNeeded: str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC - add R1, SP, #0x60 @ We pushed 0x60 bytes on the stack - str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP - @ R0 is ExceptionType mov R1,SP @ R1 is SystemContext @@ -253,7 +255,7 @@ NoAdjustNeeded: subne SP, SP, #4 @ Adjust SP if not 8-byte aligned /* -VOID +EFI_STATUS EFIAPI CommonCExceptionHandler ( IN EFI_EXCEPTION_TYPE ExceptionType, R0 @@ -261,6 +263,8 @@ CommonCExceptionHandler ( ) */ + mov R5, R0 @ R5 is ExceptionType + blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler mov SP, R4 @ Restore SP @@ -275,25 +279,14 @@ CommonCExceptionHandler ( ldr R1, [SP, #0x44] @ Restore EFI_SYSTEM_CONTEXT_ARM.DFSR mcr p15, 0, R1, c5, c0, 0 @ Write DFSR - ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC - str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored - - ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR - str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored - - add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry - add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR - and R1, R1, #0x1f @ Check to see if User or System Mode - cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f)) - cmpne R1, #0x10 @ - ldmibeq R2, {lr}^ @ restore unbanked lr + cmp R5, #2 @ if (ExceptionType == SoftwareInterrupt) + addeq SP, SP, #0x4 @ Preserve EFI_STATUS return result in R0. + ldmfdeq SP!, {R1-R12} @ @ else - ldmibne R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR} + ldmfdne SP!, {R0-R12} @ Restore general purpose registers - ldmfd SP!,{R0-R12} @ Restore general purpose registers @ Exception handler can not change SP add SP,SP,#0x20 @ Clear out the remaining stack space ldmfd SP!,{LR} @ restore the link register for this context rfefd SP! @ return from exception via srsfd stack slot - diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 3793a72255..5527821b22 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -22,6 +22,7 @@ #include #include #include +#include // // Maximum number of characters to print to serial (UINT8s) and to console if @@ -29,14 +30,6 @@ // #define MAX_PRINT_CHARS 100 -typedef -EFI_STATUS -(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ); - STATIC CHAR8 *gExceptionTypeString[] = { "Synchronous", "IRQ", @@ -195,10 +188,10 @@ BaseName ( VOID EFIAPI InitializeSysCallHandler ( - IN VOID *Handler + IN EFI_SYS_CALL_BOOT_SERVICE Handler ) { - mSysCallHandler = (EFI_SYS_CALL_BOOT_SERVICE)Handler; + mSysCallHandler = Handler; } /** diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c index 006db6d517..6293843f32 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c @@ -39,6 +39,8 @@ typedef struct { CHAR8 Char; } CPSR_CHAR; +STATIC EFI_SYS_CALL_BOOT_SERVICE mSysCallHandler; + STATIC CONST CPSR_CHAR mCpsrChar[] = { { 31, 'n' }, { 30, 'z' }, @@ -187,6 +189,15 @@ STATIC CHAR8 *gExceptionTypeString[] = { "FIQ" }; +VOID +EFIAPI +InitializeSysCallHandler ( + IN EFI_SYS_CALL_BOOT_SERVICE Handler + ) +{ + mSysCallHandler = Handler; +} + /** This is the default action to take on an unexpected exception @@ -212,6 +223,14 @@ DefaultExceptionHandler ( BOOLEAN DfsrWrite; UINT32 PcAdjust; + if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) { + return mSysCallHandler ( + SystemContext.SystemContextArm->R0, + &(SystemContext.SystemContextArm->R1), + &(SystemContext.SystemContextArm->SP) + ); + } + PcAdjust = 0; CharCount = AsciiSPrint ( diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index cdbbacf501..718812ad43 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -22,26 +22,6 @@ ASM_FUNC(CallInstallMultipleProtocolInterfaces) bx LR -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CoreBootServices ( -// IN UINT8 Type, -// ... -// ); -// -// (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -// (rdx) Argument 1 of the called function. -// (r8) Argument 2 of the called function. -// (r9) Argument 3 of the called function. -// (r10) Type. -// (r11) RFLAGS saved by SYSCALL in SysCall(). -// -// (On User Stack) Argument 4, 5, ... -//------------------------------------------------------------------------------ -ASM_FUNC(CoreBootServices) - bx LR - //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index adf5509d06..f07ba49e2c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -6,6 +6,7 @@ **/ #include +#include #include "DxeMain.h" @@ -33,6 +34,50 @@ ArmClearPan ( VOID ); +STATIC +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), + &Physical + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + // + // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. + // + CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); + // + // All remaining arguments are on User Stack. + // + CopyMem ((VOID *)((UINTN)Physical + 4 * sizeof (UINTN)), (VOID *)UserRsp, 5 * sizeof (UINTN)); + EnableSMAP (); + + Status = CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)(UINTN)Physical + ); + + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + + return Status; +} + VOID EFIAPI InitializeMsr ( @@ -49,6 +94,8 @@ InitializeMsr ( DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); // ASSERT (FALSE); } + + InitializeSysCallHandler (SysCallBootService); } VOID