Skip to content

Commit

Permalink
Ring3: Placed UnicodeCollation driver into User space.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikhail Krichanov committed Jan 17, 2025
1 parent cd65706 commit 3f3f7fa
Show file tree
Hide file tree
Showing 13 changed files with 182 additions and 96 deletions.
31 changes: 14 additions & 17 deletions ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@
UINT64 ESR; 0x318 // Exception syndrome register
UINT64 FAR; 0x320 // Fault Address Register
UINT64 Type; 0x328 // Exception Type
UINT64 TTBR0; 0x330 // User Page Table
UINT64 Padding;0x338 // Alignment requirement
*/

GCC_ASM_EXPORT(ExceptionHandlersEnd)
Expand All @@ -99,7 +101,7 @@ GCC_ASM_EXPORT(CommonCExceptionHandler)

#define GP_CONTEXT_SIZE (32 * 8)
#define FP_CONTEXT_SIZE (32 * 16)
#define SYS_CONTEXT_SIZE ( 6 * 8) // 5 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)
#define SYS_CONTEXT_SIZE ( 8 * 8) // 7 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)

ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096)

Expand Down Expand Up @@ -264,6 +266,11 @@ ASM_PFX(CommonExceptionEntry):
stp x2, x3, [x28, #-SYS_CONTEXT_SIZE]!
stp x4, x5, [x28, #0x10]
stp x6, x0, [x28, #0x20]
EL1_OR_EL2(x1)
1:mrs x2, ttbr0_el1
b 3f
2:mrs x2, ttbr0_el2
3:stp x2, xzr, [x28, #0x30]

// Push FP regs to Stack.
stp q0, q1, [x28, #-FP_CONTEXT_SIZE]!
Expand All @@ -288,17 +295,12 @@ ASM_PFX(CommonExceptionEntry):
cmp x2, 0 // Check whether EL0 process was interrupted
b.ne NoTTBR0Switch
adrp x1, ASM_PFX(CorePageTable)
ldr x4, [x1]
EL1_OR_EL2(x3)
1:mrs x4, ttbr0_el1
str x4, [x1, #0x8] // UserPageTable
ldr x4, [x1] // CorePageTable
msr ttbr0_el1, x4
1:msr ttbr0_el1, x4
tlbi vmalle1
b 3f
2:mrs x4, ttbr0_el2
str x4, [x1, #0x8] // UserPageTable
ldr x4, [x1] // CorePageTable
msr ttbr0_el2, x4
2:msr ttbr0_el2, x4
tlbi alle2
3:dsb sy
isb
Expand All @@ -324,14 +326,12 @@ NoTTBR0Switch:
and x2, x2, #0xF
cmp x2, 0 // Check whether EL0 process was interrupted
b.ne NoTTBR0Switch2
adrp x1, ASM_PFX(CorePageTable)
ldr x4, [x28, #(FP_CONTEXT_SIZE + 0x30)] // UserPageTable
EL1_OR_EL2(x3)
1:ldr x4, [x1, #0x8] // UserPageTable
msr ttbr0_el1, x4
1:msr ttbr0_el1, x4
tlbi vmalle1
b 3f
2:ldr x4, [x1, #0x8] // UserPageTable
msr ttbr0_el2, x4
2:msr ttbr0_el2, x4
tlbi alle2
3:dsb sy
isb
Expand Down Expand Up @@ -428,9 +428,6 @@ ASM_FUNC(RegisterEl0Stack)
ASM_PFX(CorePageTable):
.ds.d 1

UserPageTable:
.ds.d 1

.balign 4096
Padding:
.ds.b 1
35 changes: 21 additions & 14 deletions ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ 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 0x58 # pushed by srsfd
CPSR 0x5c
TTBR0 0x58
Padding 0x5c

LR 0x60 # pushed by srsfd
CPSR 0x64

*/

Expand Down Expand Up @@ -98,7 +101,7 @@ ASM_PFX(Fiq):
ASM_PFX(ResetEntry):
srsdb #0x13! @ Store return state on SVC stack
@ We are already in SVC mode

sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -111,6 +114,7 @@ ASM_PFX(UndefinedInstructionEntry):
sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -124,6 +128,7 @@ ASM_PFX(SoftwareInterruptEntry):
isb
srsdb #0x13! @ Store return state on SVC stack
@ We are already in SVC mode
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -136,6 +141,7 @@ ASM_PFX(PrefetchAbortEntry):
sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -148,6 +154,7 @@ ASM_PFX(DataAbortEntry):
sub LR,LR,#8
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -159,6 +166,7 @@ ASM_PFX(DataAbortEntry):
ASM_PFX(ReservedExceptionEntry):
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -171,6 +179,7 @@ ASM_PFX(IrqEntry):
sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -183,6 +192,7 @@ ASM_PFX(FiqEntry):
sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand Down Expand Up @@ -217,7 +227,7 @@ ASM_PFX(AsmCommonExceptionEntry):
mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR

ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
ldr R1, [SP, #0x64] @ srsdb saved pre-exception CPSR on the stack
str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR

add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
Expand All @@ -229,20 +239,20 @@ ASM_PFX(AsmCommonExceptionEntry):
stmdaeq R2, {sp}^ @ save unbanked sp
@ else
stmdane R2, {lr} @ save SVC lr
addne R1, SP, #0x60 @ We pushed 0x60 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


ldr R5, [SP, #0x58] @ 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
sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType == 2)) {
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
ldr R1, [SP, #0x64] @ 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
strne R5,[SP,#0x60] @ Update LR value pushed by srsfd

NoAdjustNeeded:

Expand All @@ -260,8 +270,7 @@ NoAdjustNeeded:
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]
str R5, [SP, #0x58]
and R5, R5, #0x7F @ Preserve TTBR0 attributes
LDRL (R6, ASM_PFX(CorePageTable))
orr R6, R6, R5 @ Assign TTBR0 attributes
Expand Down Expand Up @@ -296,7 +305,7 @@ CommonCExceptionHandler (
and R4, R4, #0xF
cmp R4, 0 @ Check whether EL0 process was interrupted
bne NoTTBR0Switch2
LDRL (R4, UserPageTable)
ldr R4, [SP, #0x58] @ User Page Table
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.
Expand Down Expand Up @@ -325,6 +334,7 @@ NoTTBR0Switch2:

add SP,SP,#0x20 @ Clear out the remaining stack space
ldmfd SP!,{LR} @ restore the link register for this context
add SP, SP, #0x8 @ Clear out TTBR0 and Padding
rfefd SP! @ return from exception via srsfd stack slot

ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096)
Expand All @@ -336,9 +346,6 @@ ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096)
ASM_PFX(CorePageTable):
.ds.l 1

UserPageTable:
.ds.l 1

.balign 4096
Padding:
.ds.b 1
2 changes: 1 addition & 1 deletion ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ APRIORI DXE {
INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
INF USER FatPkg/EnhancedFatDxe/Fat.inf
INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf

Expand Down
6 changes: 4 additions & 2 deletions MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ ASM_FUNC(ArmCallRing3)
stp q12, q13, [sp, #0xa0]
stp q14, q15, [sp, #0x80]

stp xzr, x16, [sp, #0x70]
mrs x6, sp_el0
stp x6, x16, [sp, #0x70]
stp x17, x18, [sp, #0x60]
stp x19, x20, [sp, #0x50]
stp x21, x22, [sp, #0x40]
Expand Down Expand Up @@ -138,7 +139,7 @@ ASM_FUNC(ReturnToCore)
ldp q12, q13, [sp, #0xa0]
ldp q14, q15, [sp, #0x80]

ldr x16, [sp, #0x78]
ldp x6, x16, [sp, #0x70]
ldp x17, x18, [sp, #0x60]
ldp x19, x20, [sp, #0x50]
ldp x21, x22, [sp, #0x40]
Expand All @@ -147,6 +148,7 @@ ASM_FUNC(ReturnToCore)
ldp x27, x28, [sp, #0x10]
ldp x29, x30, [sp]
add sp, sp, #0x100
msr sp_el0, x6
// Enable interrupts.
msr daifclr, #0xf
isb
Expand Down
5 changes: 1 addition & 4 deletions MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

#include "DxeMain.h"

STATIC UINTN mSysCallStackTop;
UINTN gUserPageTable;
UINTN gUserPageTable;

EFI_STATUS
EFIAPI
Expand Down Expand Up @@ -156,8 +155,6 @@ CallRing3 (
IN UINTN *ReturnSP
)
{
mSysCallStackTop = SysCallStackTop;

return ArmCallRing3 (
Data,
UserStackTop,
Expand Down
7 changes: 7 additions & 0 deletions MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ ASM_FUNC(ArmCallRing3)
ldr R6, [SP, #0x28]
// R7 is gUserPageTable
ldr R7, [SP, #0x2C]
// Save old SP_usr on Core Stack.
sub SP, SP, #0x8
stmia SP, {SP}^

#if (FixedPcdGet32(PcdVFPEnabled))
// Save vstm registers in case they are used in optimizations.
Expand Down Expand Up @@ -135,6 +138,10 @@ ASM_FUNC(ReturnToCore)
vpop {d0-d15}
#endif

// Restore old SP_usr.
ldmia SP, {SP}^
add SP, SP, #0x8

pop {R4-R12, LR}

// Enable interrupts.
Expand Down
5 changes: 1 addition & 4 deletions MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

#include "DxeMain.h"

STATIC UINTN mSysCallStackTop;
UINTN gUserPageTable;
UINTN gUserPageTable;

EFI_STATUS
EFIAPI
Expand Down Expand Up @@ -151,8 +150,6 @@ CallRing3 (
IN UINTN *ReturnSP
)
{
mSysCallStackTop = SysCallStackTop;

return ArmCallRing3 (
Data,
UserStackTop,
Expand Down
26 changes: 18 additions & 8 deletions MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm
Original file line number Diff line number Diff line change
Expand Up @@ -180,24 +180,27 @@ ASM_PFX(CallRing3):
push ebp
push edi
push esi
; Save old SysCallStackTop.
push dword MSR_IA32_SYSENTER_ESP
call ASM_PFX(AsmReadMsr64)
pop ebx
push eax

; Save Core Stack pointer.
mov ebx, [esp + 4 * 8] ; ReturnSP
mov ebx, [esp + 4 * 9] ; ReturnSP
mov [ebx], esp

mov ebx, [esp + 4 * 7]
mov [ASM_PFX(SysCallStackTop)], ebx
mov edx, 0
mov eax, ebx
mov eax, [esp + 4 * 8] ; SysCallStackTop
mov ecx, MSR_IA32_SYSENTER_ESP
wrmsr

SetRing3DataSegmentSelectors

; Prepare SYSEXIT arguments.
mov ecx, [esp + 4 * 6] ; UserStackTop
mov ecx, [esp + 4 * 7] ; UserStackTop
mov edx, [ASM_PFX(gRing3EntryPoint)]
mov eax, [esp + 4 * 5] ; Data
mov eax, [esp + 4 * 6] ; Data

; Switch to User Stack.
mov ebp, ecx
Expand All @@ -223,8 +226,15 @@ ASM_PFX(SysCallEnd):
;------------------------------------------------------------------------------
global ASM_PFX(ReturnToCore)
ASM_PFX(ReturnToCore):
mov eax, [esp + 4] ; Status
mov ebx, [esp + 4] ; Status
mov esp, [esp + 4*2] ; ReturnSP
; Restore old SysCallStackTop.
mov edx, 0
pop eax
mov ecx, MSR_IA32_SYSENTER_ESP
wrmsr

mov eax, ebx
pop esi
pop edi
pop ebp
Expand All @@ -245,5 +255,5 @@ ASM_PFX(gUserPageTable):
resd 1

ALIGN 4096
ASM_PFX(SysCallStackTop):
Padding:
resd 1
Loading

0 comments on commit 3f3f7fa

Please sign in to comment.