Ring3: Refactored out SysCallStackTop.

This commit is contained in:
Mikhail Krichanov 2025-01-21 23:07:38 +03:00
parent 502bafe41b
commit b13baeb518
13 changed files with 56 additions and 94 deletions

View File

@ -231,7 +231,6 @@ typedef struct {
VOID *HiiData; VOID *HiiData;
BOOLEAN IsUserImage; BOOLEAN IsUserImage;
UINTN UserPageTable; UINTN UserPageTable;
UINTN SysCallStackTop;
UINTN UserStackTop; UINTN UserStackTop;
} LOADED_IMAGE_PRIVATE_DATA; } LOADED_IMAGE_PRIVATE_DATA;
@ -240,7 +239,6 @@ typedef struct {
VOID *UserSpaceDriver; VOID *UserSpaceDriver;
UINTN UserPageTable; UINTN UserPageTable;
UINTN UserStackTop; UINTN UserStackTop;
UINTN SysCallStackTop;
LIST_ENTRY Link; LIST_ENTRY Link;
} USER_SPACE_DRIVER; } USER_SPACE_DRIVER;
@ -2792,8 +2790,6 @@ UINTN
EFIAPI EFIAPI
InitializeUserPageTable ( InitializeUserPageTable (
IN LOADED_IMAGE_PRIVATE_DATA *Image, IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN UINTN SysCallStackBase,
IN UINTN SysCallStackSize,
IN UINTN UserStackBase, IN UINTN UserStackBase,
IN UINTN UserStackSize IN UINTN UserStackSize
); );

View File

@ -26,15 +26,13 @@ ASM_PFX(SysCall):
jg continue jg continue
push r9 push r9
push r8 push r8
mov r8, rsp lea r8, [rsp - 8]
sub r8, 8
add rsp, 8*2 add rsp, 8*2
jmp makecall jmp makecall
continue: continue:
mov [rsp + 8*4], r9 mov [rsp + 8*4], r9
mov [rsp + 8*3], r8 mov [rsp + 8*3], r8
mov r8, rsp lea r8, [rsp + 8*2]
add r8, 8*2
makecall: makecall:
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
syscall syscall

View File

@ -1132,7 +1132,6 @@ CoreLoadImageCommon (
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINT8 ImageOrigin; UINT8 ImageOrigin;
EFI_FV_FILE_ATTRIBUTES FileAttributes; EFI_FV_FILE_ATTRIBUTES FileAttributes;
UINTN SysCallStackBase;
UINTN UserStackBase; UINTN UserStackBase;
SecurityStatus = EFI_SUCCESS; SecurityStatus = EFI_SUCCESS;
@ -1471,16 +1470,11 @@ CoreLoadImageCommon (
ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage);
if ((gRing3Data != NULL) && Image->IsUserImage) { if ((gRing3Data != NULL) && Image->IsUserImage) {
Image->SysCallStackTop = AllocateStack (STACK_SIZE, &SysCallStackBase);
SetUefiImageMemoryAttributes (SysCallStackBase, STACK_SIZE, EFI_MEMORY_XP);
Image->UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase); Image->UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase);
SetUefiImageMemoryAttributes (UserStackBase, STACK_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER); SetUefiImageMemoryAttributes (UserStackBase, STACK_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER);
Image->UserPageTable = InitializeUserPageTable ( Image->UserPageTable = InitializeUserPageTable (
Image, Image,
SysCallStackBase,
STACK_SIZE,
UserStackBase, UserStackBase,
STACK_SIZE STACK_SIZE
); );
@ -1749,7 +1743,6 @@ CoreStartImage (
UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint; UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint;
UserDriver->UserPageTable = Image->UserPageTable; UserDriver->UserPageTable = Image->UserPageTable;
UserDriver->UserStackTop = Image->UserStackTop; UserDriver->UserStackTop = Image->UserStackTop;
UserDriver->SysCallStackTop = Image->SysCallStackTop;
InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link);

View File

@ -61,15 +61,13 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// EFIAPI // EFIAPI
// CallRing3 ( // CallRing3 (
// IN RING3_CALL_DATA *Data, // IN RING3_CALL_DATA *Data,
// IN UINTN UserStackTop, // IN UINTN UserStackTop
// IN UINTN SysCallStackTop
// ); // );
// //
// (x0) Data // (x0) Data
// (x1) UserStackTop // (x1) UserStackTop
// (x2) gRing3EntryPoint // (x2) gRing3EntryPoint
// (x3) SysCallStackTop // (x3) gUserPageTable
// (x4) gUserPageTable
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3) ASM_FUNC(ArmCallRing3)
// Save registers. // Save registers.
@ -92,10 +90,6 @@ ASM_FUNC(ArmCallRing3)
// Disable interrupts. // Disable interrupts.
msr daifset, #0xf msr daifset, #0xf
isb isb
// Switch to SysCallStackTop and save ReturnSP on it.
mov x6, sp
mov sp, x3
stp x6, xzr, [sp, #-0x10]!
// Copy PSTATE to SPSR. // Copy PSTATE to SPSR.
mrs x6, nzcv mrs x6, nzcv
mrs x7, pan mrs x7, pan
@ -105,12 +99,12 @@ ASM_FUNC(ArmCallRing3)
EL1_OR_EL2(x1) EL1_OR_EL2(x1)
1:msr elr_el1, x2 1:msr elr_el1, x2
msr spsr_el1, x6 msr spsr_el1, x6
msr ttbr0_el1, x4 msr ttbr0_el1, x3
tlbi vmalle1 tlbi vmalle1
b 3f b 3f
2:msr elr_el2, x2 2:msr elr_el2, x2
msr spsr_el2, x6 msr spsr_el2, x6
msr ttbr0_el2, x4 msr ttbr0_el2, x3
tlbi alle2 tlbi alle2
3:dsb sy 3:dsb sy
isb isb

View File

@ -20,7 +20,6 @@ ArmCallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN UINTN SysCallStackTop,
IN UINTN UserPageTable IN UINTN UserPageTable
); );
@ -54,7 +53,7 @@ SysCallBootService (
Context.SystemContextAArch64->X0, Context.SystemContextAArch64->X0,
Context.SystemContextAArch64->X1, Context.SystemContextAArch64->X1,
(UINTN *)Physical, (UINTN *)Physical,
*(UINTN *)Context.SystemContextAArch64->SP Context.SystemContextAArch64->SP
); );
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (7 * sizeof (UINTN))); CoreFreePages (Physical, EFI_SIZE_TO_PAGES (7 * sizeof (UINTN)));
@ -149,15 +148,13 @@ EFI_STATUS
EFIAPI EFIAPI
CallRing3 ( CallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop
IN UINTN SysCallStackTop
) )
{ {
return ArmCallRing3 ( return ArmCallRing3 (
Data, Data,
UserStackTop, UserStackTop,
gRing3EntryPoint, gRing3EntryPoint,
SysCallStackTop,
gUserPageTable gUserPageTable
); );
} }

View File

@ -57,22 +57,17 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// EFIAPI // EFIAPI
// CallRing3 ( // CallRing3 (
// IN RING3_CALL_DATA *Data, // IN RING3_CALL_DATA *Data,
// IN UINTN UserStackTop, // IN UINTN UserStackTop
// IN UINTN SysCallStackTop
// ); // );
// //
// (r0) Data // (r0) Data
// (r1) UserStackTop // (r1) UserStackTop
// (r2) gRing3EntryPoint // (r2) gRing3EntryPoint
// (r3) SysCallStackTop // (r3) gUserPageTable
//
// (On Core Stack) gUserPageTable
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3) ASM_FUNC(ArmCallRing3)
// Save registers. // Save registers.
push {R4-R12, LR} push {R4-R12, LR}
// R7 is gUserPageTable
ldr R7, [SP, #0x28]
// Save old SP_usr and LR_usr on Core Stack. // Save old SP_usr and LR_usr on Core Stack.
sub SP, SP, #0x8 sub SP, SP, #0x8
stmia SP, {SP, LR}^ stmia SP, {SP, LR}^
@ -95,17 +90,11 @@ ASM_FUNC(ArmCallRing3)
// Set SPSR M[3:0] bits to User mode. // Set SPSR M[3:0] bits to User mode.
and R4, R4, #0xFFFFFFF0 and R4, R4, #0xFFFFFFF0
// Switch to SysCallStackTop and save ReturnSP on it.
mov R5, SP
mov SP, R3
push {R5}
push {R5} // Align stack on 8 bytes
// Switch to UserPageTable. // Switch to UserPageTable.
mrc p15,0,R8,c2,c0,0 // R8 == TTBR0 mrc p15,0,R8,c2,c0,0 // R8 == TTBR0
and R8, R8, #0x7F // Preserve Core TTBR0 attributes. and R8, R8, #0x7F // Preserve Core TTBR0 attributes.
orr R7, R7, R8 // Assign Core attributes to UserPageTable. orr R3, R3, R8 // Assign Core attributes to UserPageTable.
mcr p15,0,R7,c2,c0,0 // TTBR0 == UserPageTable mcr p15,0,R3,c2,c0,0 // TTBR0 == UserPageTable
mcr p15,0,r0,c8,c7,0 // TLBIALL, TLB Invalidate All. mcr p15,0,r0,c8,c7,0 // TLBIALL, TLB Invalidate All.
mcr p15,0,r0,c7,c5,6 // BPIALL, Branch Predictor Invalidate All. mcr p15,0,r0,c7,c5,6 // BPIALL, Branch Predictor Invalidate All.
dsb dsb

View File

@ -19,7 +19,6 @@ ArmCallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN UINTN SysCallStackTop,
IN UINTN UserPageTable IN UINTN UserPageTable
); );
@ -94,7 +93,7 @@ SysCallBootService (
Type, Type,
NumberOfArguments, NumberOfArguments,
(UINTN *)(UINTN)Physical, (UINTN *)(UINTN)Physical,
*(UINTN *)Context.SystemContextArm->SP_EL1 Context.SystemContextArm->SP_EL1
); );
// //
// TODO: Fix memory leak for ReturnToCore(). // TODO: Fix memory leak for ReturnToCore().
@ -178,15 +177,13 @@ EFI_STATUS
EFIAPI EFIAPI
CallRing3 ( CallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop
IN UINTN SysCallStackTop
) )
{ {
return ArmCallRing3 ( return ArmCallRing3 (
Data, Data,
UserStackTop, UserStackTop,
gRing3EntryPoint, gRing3EntryPoint,
SysCallStackTop,
gUserPageTable gUserPageTable
); );
} }

View File

@ -523,7 +523,6 @@ CallBootService (
NewDriver->UserSpaceDriver = UserArgList[Index + 1]; NewDriver->UserSpaceDriver = UserArgList[Index + 1];
NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->UserStackTop = UserDriver->UserStackTop;
NewDriver->SysCallStackTop = UserDriver->SysCallStackTop;
InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link);

View File

@ -134,7 +134,7 @@ ASM_PFX(CoreBootServices):
; Prepare CallBootService arguments. ; Prepare CallBootService arguments.
mov ebp, esp mov ebp, esp
mov eax, [esp + 4*3] lea eax, [esp + 4*3]
push eax ; ReturnSP push eax ; ReturnSP
add edx, 4*3 add edx, 4*3
push edx ; User Arguments[] push edx ; User Arguments[]
@ -169,11 +169,10 @@ ASM_PFX(CoreBootServices):
; EFIAPI ; EFIAPI
; CallRing3 ( ; CallRing3 (
; IN RING3_CALL_DATA *Data, ; IN RING3_CALL_DATA *Data,
; IN UINTN UserStackTop, ; IN UINTN UserStackTop
; IN UINTN SysCallStackTop
; ); ; );
; ;
; (On User Stack) Data, UserStackTop, SysCallStackTop ; (On User Stack) Data, UserStackTop
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
global ASM_PFX(CallRing3) global ASM_PFX(CallRing3)
ASM_PFX(CallRing3): ASM_PFX(CallRing3):
@ -191,14 +190,10 @@ ASM_PFX(CallRing3):
; Set new SysCallStackTop. ; Set new SysCallStackTop.
mov edx, 0 mov edx, 0
mov eax, [esp + 4 * 8] ; SysCallStackTop mov eax, esp
sub eax, 4
mov ecx, MSR_IA32_SYSENTER_ESP mov ecx, MSR_IA32_SYSENTER_ESP
wrmsr wrmsr
; Save ReturnSP on SysCallStack.
mov [eax], esp
SetRing3DataSegmentSelectors SetRing3DataSegmentSelectors
; Prepare SYSEXIT arguments. ; Prepare SYSEXIT arguments.

View File

@ -144,8 +144,8 @@ InitializeMsr (
} }
// //
// Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP and // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP for SYSENTER and SYSEXIT.
// MSR_IA32_SYSENTER_ESP for SYSENTER and SYSEXIT. // MSR_IA32_SYSENTER_ESP is set in CallRing3().
// //
Msr = RING0_CODE32_SEL; Msr = RING0_CODE32_SEL;
AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr); AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr);

View File

@ -14,10 +14,12 @@ RING3_DATA *gRing3Data;
VOID *gRing3Interfaces; VOID *gRing3Interfaces;
UINTN gUartBaseAddress; UINTN gUartBaseAddress;
UEFI_IMAGE_RECORD *mDxeRing3; UEFI_IMAGE_RECORD *mDxeRing3;
EXCEPTION_ADDRESSES *mExceptionAddresses; EXCEPTION_ADDRESSES *mExceptionAddresses;
UINTN mConfigurationTable; UINTN mConfigurationTable;
UINTN mConfigurationTableSize; UINTN mConfigurationTableSize;
EFI_PHYSICAL_ADDRESS mCoreStackBase;
UINT64 mCoreStackSize;
extern UINTN SysCallBase; extern UINTN SysCallBase;
extern UINTN SysCallEnd; extern UINTN SysCallEnd;
@ -43,12 +45,14 @@ InitializeRing3 (
IN LOADED_IMAGE_PRIVATE_DATA *Image IN LOADED_IMAGE_PRIVATE_DATA *Image
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical; EFI_PHYSICAL_ADDRESS Physical;
UINTN Index; UINTN Index;
EFI_CONFIGURATION_TABLE *Conf; EFI_CONFIGURATION_TABLE *Conf;
EARLY_PL011_BASE_ADDRESS *UartBase; EARLY_PL011_BASE_ADDRESS *UartBase;
CONST VOID *Hob; CONST VOID *Hob;
EFI_PEI_HOB_POINTERS PeiHob;
EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
// //
// Set Ring3 EntryPoint and BootServices. // Set Ring3 EntryPoint and BootServices.
@ -158,6 +162,18 @@ InitializeRing3 (
mExceptionAddresses = GetExceptionAddresses (); mExceptionAddresses = GetExceptionAddresses ();
PeiHob.Raw = GetHobList ();
while ((PeiHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, PeiHob.Raw)) != NULL) {
MemoryHob = PeiHob.MemoryAllocation;
if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &MemoryHob->AllocDescriptor.Name)) {
mCoreStackBase = MemoryHob->AllocDescriptor.MemoryBaseAddress;
mCoreStackSize = MemoryHob->AllocDescriptor.MemoryLength;
break;
}
PeiHob.Raw = GET_NEXT_HOB (PeiHob);
}
return Status; return Status;
} }
@ -165,8 +181,6 @@ UINTN
EFIAPI EFIAPI
InitializeUserPageTable ( InitializeUserPageTable (
IN LOADED_IMAGE_PRIVATE_DATA *Image, IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN UINTN SysCallStackBase,
IN UINTN SysCallStackSize,
IN UINTN UserStackBase, IN UINTN UserStackBase,
IN UINTN UserStackSize IN UINTN UserStackSize
) )
@ -226,7 +240,7 @@ InitializeUserPageTable (
} }
// //
// Map CoreBootServices, SysCallStackBase // Map CoreBootServices, CoreStackBase
// //
gCpu->SetUserMemoryAttributes ( gCpu->SetUserMemoryAttributes (
gCpu, gCpu,
@ -239,8 +253,8 @@ InitializeUserPageTable (
gCpu->SetUserMemoryAttributes ( gCpu->SetUserMemoryAttributes (
gCpu, gCpu,
UserPageTable, UserPageTable,
SysCallStackBase, mCoreStackBase,
SysCallStackSize, mCoreStackSize,
EFI_MEMORY_XP EFI_MEMORY_XP
); );

View File

@ -14,8 +14,7 @@ EFI_STATUS
EFIAPI EFIAPI
CallRing3 ( CallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop
IN UINTN SysCallStackTop
); );
EFI_STATUS EFI_STATUS
@ -64,8 +63,7 @@ GoToRing3 (
// //
Status = CallRing3 ( Status = CallRing3 (
Input, Input,
UserDriver->UserStackTop, UserDriver->UserStackTop
UserDriver->SysCallStackTop
); );
CoreFreePages (Ring3Pages, PagesNumber); CoreFreePages (Ring3Pages, PagesNumber);
@ -755,7 +753,6 @@ CoreFileOpen (
NewDriver->CoreWrapper = NewFile; NewDriver->CoreWrapper = NewFile;
NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->UserStackTop = UserDriver->UserStackTop;
NewDriver->SysCallStackTop = UserDriver->SysCallStackTop;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
NewDriver->UserSpaceDriver = *Ring3NewHandle; NewDriver->UserSpaceDriver = *Ring3NewHandle;
@ -857,7 +854,6 @@ CoreOpenVolume (
NewDriver->CoreWrapper = File; NewDriver->CoreWrapper = File;
NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->UserStackTop = UserDriver->UserStackTop;
NewDriver->SysCallStackTop = UserDriver->SysCallStackTop;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
NewDriver->UserSpaceDriver = *Ring3Root; NewDriver->UserSpaceDriver = *Ring3Root;

View File

@ -149,9 +149,8 @@ ASM_PFX(CoreBootServices):
sub rsp, 8*4 sub rsp, 8*4
; Prepare CallBootService arguments. ; Prepare CallBootService arguments.
mov rcx, r10 ; Type mov rcx, r10 ; Type
mov rax, [ASM_PFX(SysCallStackTop)] mov r9, [ASM_PFX(SysCallStackTop)] ; ReturnSP
mov r9, [rax] ; ReturnSP
sti sti
call ASM_PFX(CallBootService) call ASM_PFX(CallBootService)
@ -184,13 +183,11 @@ o64 sysret
; EFIAPI ; EFIAPI
; CallRing3 ( ; CallRing3 (
; IN RING3_CALL_DATA *Data, ; IN RING3_CALL_DATA *Data,
; IN UINTN UserStackTop, ; IN UINTN UserStackTop
; IN UINTN SysCallStackTop
; ); ; );
; ;
; (rcx) Data ; (rcx) Data
; (rdx) UserStackTop ; (rdx) UserStackTop
; (r8) SysCallStackTop
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
global ASM_PFX(CallRing3) global ASM_PFX(CallRing3)
ASM_PFX(CallRing3): ASM_PFX(CallRing3):
@ -206,15 +203,12 @@ ASM_PFX(CallRing3):
push r13 push r13
push r14 push r14
push r15 push r15
; Save old SysCallStackTop, set the new one.
push qword [ASM_PFX(SysCallStackTop)] push qword [ASM_PFX(SysCallStackTop)]
mov [ASM_PFX(SysCallStackTop)], rsp
; Save ReturnSP on SysCallStack.
sub r8, 8
mov [r8], rsp
; Save input Arguments. ; Save input Arguments.
mov rbx, rdx mov rbx, rdx
mov [ASM_PFX(SysCallStackTop)], r8
mov r10, rcx mov r10, rcx
SetRing3DataSegmentSelectors SetRing3DataSegmentSelectors