Ring3: Refactored out SysCallStackTop.

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -57,22 +57,17 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// EFIAPI
// CallRing3 (
// IN RING3_CALL_DATA *Data,
// IN UINTN UserStackTop,
// IN UINTN SysCallStackTop
// IN UINTN UserStackTop
// );
//
// (r0) Data
// (r1) UserStackTop
// (r2) gRing3EntryPoint
// (r3) SysCallStackTop
//
// (On Core Stack) gUserPageTable
// (r3) gUserPageTable
//------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3)
// Save registers.
push {R4-R12, LR}
// R7 is gUserPageTable
ldr R7, [SP, #0x28]
// Save old SP_usr and LR_usr on Core Stack.
sub SP, SP, #0x8
stmia SP, {SP, LR}^
@ -95,17 +90,11 @@ ASM_FUNC(ArmCallRing3)
// Set SPSR M[3:0] bits to User mode.
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.
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
orr R3, R3, R8 // Assign Core attributes to 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,c7,c5,6 // BPIALL, Branch Predictor Invalidate All.
dsb

View File

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

View File

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

View File

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

View File

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

View File

@ -14,10 +14,12 @@ RING3_DATA *gRing3Data;
VOID *gRing3Interfaces;
UINTN gUartBaseAddress;
UEFI_IMAGE_RECORD *mDxeRing3;
EXCEPTION_ADDRESSES *mExceptionAddresses;
UINTN mConfigurationTable;
UINTN mConfigurationTableSize;
UEFI_IMAGE_RECORD *mDxeRing3;
EXCEPTION_ADDRESSES *mExceptionAddresses;
UINTN mConfigurationTable;
UINTN mConfigurationTableSize;
EFI_PHYSICAL_ADDRESS mCoreStackBase;
UINT64 mCoreStackSize;
extern UINTN SysCallBase;
extern UINTN SysCallEnd;
@ -43,12 +45,14 @@ InitializeRing3 (
IN LOADED_IMAGE_PRIVATE_DATA *Image
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical;
UINTN Index;
EFI_CONFIGURATION_TABLE *Conf;
EARLY_PL011_BASE_ADDRESS *UartBase;
CONST VOID *Hob;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical;
UINTN Index;
EFI_CONFIGURATION_TABLE *Conf;
EARLY_PL011_BASE_ADDRESS *UartBase;
CONST VOID *Hob;
EFI_PEI_HOB_POINTERS PeiHob;
EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
//
// Set Ring3 EntryPoint and BootServices.
@ -158,6 +162,18 @@ InitializeRing3 (
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;
}
@ -165,8 +181,6 @@ UINTN
EFIAPI
InitializeUserPageTable (
IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN UINTN SysCallStackBase,
IN UINTN SysCallStackSize,
IN UINTN UserStackBase,
IN UINTN UserStackSize
)
@ -226,7 +240,7 @@ InitializeUserPageTable (
}
//
// Map CoreBootServices, SysCallStackBase
// Map CoreBootServices, CoreStackBase
//
gCpu->SetUserMemoryAttributes (
gCpu,
@ -239,8 +253,8 @@ InitializeUserPageTable (
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
SysCallStackBase,
SysCallStackSize,
mCoreStackBase,
mCoreStackSize,
EFI_MEMORY_XP
);

View File

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

View File

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