Skip to content

Commit

Permalink
Ring3: Added support for ARM User page table.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikhail Krichanov committed Dec 19, 2024
1 parent d051ccd commit 75c5b9e
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 16 deletions.
10 changes: 10 additions & 0 deletions ArmPkg/Include/AsmMacroIoLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@

#define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name)

#define _ASM_FUNC_ALIGN(Name, Section, Align) \
.global Name ; \
.section #Section, "ax" ; \
.type Name, %function ; \
.balign Align ; \
Name:

#define ASM_FUNC_ALIGN(Name, Align) \
_ASM_FUNC_ALIGN(ASM_PFX(Name), .text. ## Name, Align)

#define MOV32(Reg, Val) \
movw Reg, #(Val) & 0xffff ; \
movt Reg, #(Val) >> 16
Expand Down
54 changes: 53 additions & 1 deletion ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#------------------------------------------------------------------------------

#include <Library/PcdLib.h>
#include <AsmMacroIoLib.h>

/*

Expand Down Expand Up @@ -59,8 +60,10 @@ GCC_ASM_EXPORT(CommonCExceptionHandler)
#if !defined(__APPLE__)
.fpu neon @ makes vpush/vpop assemble
#endif
.align 5

ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096)

.align 5

//
// This code gets copied to the ARM vector table
Expand Down Expand Up @@ -117,6 +120,8 @@ ASM_PFX(UndefinedInstructionEntry):
bx R1

ASM_PFX(SoftwareInterruptEntry):
cpsid if
isb
srsdb #0x13! @ Store return state on SVC stack
@ We are already in SVC mode
stmfd SP!,{LR} @ Store the link register for the current mode
Expand Down Expand Up @@ -250,6 +255,24 @@ NoAdjustNeeded:
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
#endif

ldr R5, [SP, #0x40] @ Saved Processor Status Register
and R5, R5, #0xF
cmp R5, 0 @ Check whether EL0 process was interrupted
bne NoTTBR0Switch
mrc p15,0,R5,c2,c0,0 @ R5 == TTBR0
ADRL (R6, UserPageTable)
str R5, [R6]
and R5, R5, #0x7F @ Preserve TTBR0 attributes
LDRL (R6, ASM_PFX(CorePageTable))
orr R6, R6, R5 @ Assign TTBR0 attributes
mcr p15,0,R6,c2,c0,0 @ TTBR0 == R6
mcr p15,0,r0,c8,c7,0 @ TLBIALL, TLB Invalidate All.
mcr p15,0,r0,c7,c5,6 @ BPIALL, Branch Predictor Invalidate All.
dsb
isb

NoTTBR0Switch:

mov R4, SP @ Save current SP
tst R4, #4
subne SP, SP, #4 @ Adjust SP if not 8-byte aligned
Expand All @@ -269,6 +292,19 @@ CommonCExceptionHandler (

mov SP, R4 @ Restore SP

ldr R4, [SP, #0x40] @ Saved Processor Status Register
and R4, R4, #0xF
cmp R4, 0 @ Check whether EL0 process was interrupted
bne NoTTBR0Switch2
LDRL (R4, UserPageTable)
mcr p15,0,R4,c2,c0,0 @ TTBR0 == R4
mcr p15,0,r0,c8,c7,0 @ TLBIALL, TLB Invalidate All.
mcr p15,0,r0,c7,c5,6 @ BPIALL, Branch Predictor Invalidate All.
dsb
isb

NoTTBR0Switch2:

#if (FixedPcdGet32(PcdVFPEnabled))
vpop {d0-d15}
#endif
Expand All @@ -290,3 +326,19 @@ CommonCExceptionHandler (
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

ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096)

.data

.global ASM_PFX(CorePageTable)
.balign 4096
ASM_PFX(CorePageTable):
.ds.l 1

UserPageTable:
.ds.l 1

.balign 4096
Padding:
.ds.b 1
16 changes: 15 additions & 1 deletion MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ call:
pop {R4-R8, LR}
bx LR

ASM_FUNC_ALIGN(SysCallBase, 4096)
//------------------------------------------------------------------------------
// EFI_STATUS
// EFIAPI
Expand All @@ -63,13 +64,15 @@ call:
// (r2) gRing3EntryPoint
// (r3) gCoreSysCallStackTop
//
// (On Core Stack) &CoreSp
// (On Core Stack) &CoreSp, gUserPageTable
//------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3)
// Save registers.
push {R4-R12, LR}
// R6 is &CoreSp
ldr R6, [SP, #0x28]
// R7 is gUserPageTable
ldr R7, [SP, #0x2C]

#if (FixedPcdGet32(PcdVFPEnabled))
// Save vstm registers in case they are used in optimizations.
Expand All @@ -94,10 +97,21 @@ ASM_FUNC(ArmCallRing3)
str R5, [R6]
mov SP, R3

// Switch to UserPageTable.
mrc p15,0,R8,c2,c0,0 // R8 == TTBR0
and R8, R8, #0x7F // Preserve Core TTBR0 attributes.
orr R7, R7, R8 // Assign Core attributes to UserPageTable.
mcr p15,0,R7,c2,c0,0 // TTBR0 == UserPageTable
mcr p15,0,r0,c8,c7,0 // TLBIALL, TLB Invalidate All.
mcr p15,0,r0,c7,c5,6 // BPIALL, Branch Predictor Invalidate All.
dsb
isb

push {R4}
push {R2}
rfefd SP

ASM_FUNC_ALIGN(SysCallEnd, 4096)
//------------------------------------------------------------------------------
// VOID
// EFIAPI
Expand Down
22 changes: 8 additions & 14 deletions MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "DxeMain.h"

STATIC UINTN mCoreSp;
extern UINTN gUartBaseAddress;
UINTN gUserPageTable;

EFI_STATUS
EFIAPI
Expand All @@ -21,7 +21,8 @@ ArmCallRing3 (
IN VOID *StackPointer,
IN VOID *EntryPoint,
IN VOID *SysCallStack,
IN VOID *CoreStack
IN VOID *CoreStack,
IN UINTN UserPageTable
);

VOID
Expand Down Expand Up @@ -52,6 +53,8 @@ SysCallBootService (
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical;

ArmEnableInterrupts ();

Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
Expand All @@ -71,12 +74,6 @@ SysCallBootService (
// All remaining arguments are on User Stack.
//
CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN));

SetUefiImageMemoryAttributes (
gUartBaseAddress,
EFI_PAGE_SIZE,
EFI_MEMORY_XP
);
ForbidSupervisorAccessToUserMemory ();

Status = CallBootService (
Expand All @@ -89,11 +86,7 @@ SysCallBootService (
//
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)));

SetUefiImageMemoryAttributes (
gUartBaseAddress,
EFI_PAGE_SIZE,
EFI_MEMORY_XP | EFI_MEMORY_USER
);
ArmDisableInterrupts ();

return Status;
}
Expand Down Expand Up @@ -141,6 +134,7 @@ InitializeMsr (
}

InitializeSysCallHandler (SysCallBootService);
SetExceptionAddresses (NULL, 0);
}

VOID
Expand Down Expand Up @@ -171,5 +165,5 @@ CallRing3 (
IN RING3_CALL_DATA *Data
)
{
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp);
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable);
}

0 comments on commit 75c5b9e

Please sign in to comment.