Ring3: Refactored User and SysCall stacks allocation.

This commit is contained in:
Mikhail Krichanov 2025-01-10 17:51:23 +03:00
parent 8e6017ce99
commit 99b902bde1
6 changed files with 69 additions and 71 deletions

View File

@ -115,7 +115,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
/// ///
#define DEPEX_STACK_SIZE_INCREMENT 0x1000 #define DEPEX_STACK_SIZE_INCREMENT 0x1000
#define USER_STACK_SIZE 0x20000 #define STACK_SIZE 0x20000
#define RING3_INTERFACES_PAGES 20 #define RING3_INTERFACES_PAGES 20
typedef struct { typedef struct {
@ -231,6 +231,8 @@ typedef struct {
VOID *HiiData; VOID *HiiData;
BOOLEAN IsUserImage; BOOLEAN IsUserImage;
UINTN UserPageTable; UINTN UserPageTable;
UINTN SysCallStackTop;
UINTN UserStackTop;
} LOADED_IMAGE_PRIVATE_DATA; } LOADED_IMAGE_PRIVATE_DATA;
typedef struct { typedef struct {
@ -285,10 +287,8 @@ extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage;
extern RING3_DATA *gRing3Data; extern RING3_DATA *gRing3Data;
extern VOID *gRing3Interfaces; extern VOID *gRing3Interfaces;
extern VOID *gCoreSysCallStackBase; extern UINTN gCoreSysCallStackTop;
extern VOID *gCoreSysCallStackTop; extern UINTN gRing3CallStackTop;
extern VOID *gRing3CallStackBase;
extern VOID *gRing3CallStackTop;
extern VOID *gRing3EntryPoint; extern VOID *gRing3EntryPoint;
extern UINTN gUserPageTable; extern UINTN gUserPageTable;
extern UINTN gCorePageTable; extern UINTN gCorePageTable;
@ -2798,7 +2798,11 @@ FreeProtocolsList (
UINTN 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 UserStackSize
); );
#endif #endif

View File

@ -799,16 +799,6 @@ CoreExitBootServices (
RING3_INTERFACES_PAGES RING3_INTERFACES_PAGES
); );
CoreFreePages (
(EFI_PHYSICAL_ADDRESS)(UINTN)gCoreSysCallStackBase,
EFI_SIZE_TO_PAGES (USER_STACK_SIZE)
);
CoreFreePages (
(EFI_PHYSICAL_ADDRESS)(UINTN)gRing3CallStackBase,
EFI_SIZE_TO_PAGES (USER_STACK_SIZE)
);
FreeProtocolsList (); FreeProtocolsList ();
} }

View File

@ -1033,6 +1033,30 @@ CoreUnloadAndCloseImage (
CoreFreePool (Image); CoreFreePool (Image);
} }
STATIC
UINTN
EFIAPI
AllocateStack (
IN UINTN Size,
OUT UINTN *Base
)
{
UINTN TopOfStack;
ASSERT (Base != NULL);
ASSERT (IS_ALIGNED (Size, EFI_PAGE_SIZE));
*Base = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (Size));
ASSERT (*Base != 0);
//
// Compute the top of the allocated stack. Pre-allocate a UINTN for safety.
//
TopOfStack = *Base + Size - CPU_STACK_ALIGNMENT;
TopOfStack = ALIGN_VALUE (TopOfStack, CPU_STACK_ALIGNMENT);
return TopOfStack;
}
/** /**
Loads an EFI image into memory and returns a handle to the image. Loads an EFI image into memory and returns a handle to the image.
@ -1108,6 +1132,8 @@ 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;
SecurityStatus = EFI_SUCCESS; SecurityStatus = EFI_SUCCESS;
@ -1445,7 +1471,19 @@ 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->UserPageTable = InitializeUserPageTable (Image); 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
);
} }
RegisterMemoryProfileImage ( RegisterMemoryProfileImage (
@ -1703,7 +1741,9 @@ CoreStartImage (
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0); ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
gUserPageTable = Image->UserPageTable; gUserPageTable = Image->UserPageTable;
gRing3CallStackTop = Image->UserStackTop;
gCoreSysCallStackTop = Image->SysCallStackTop;
Image->Status = GoToRing3 ( Image->Status = GoToRing3 (
2, 2,

View File

@ -19,9 +19,9 @@ EFI_STATUS
EFIAPI EFIAPI
ArmCallRing3 ( ArmCallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN VOID *StackPointer, IN UINTN StackPointer,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN VOID *SysCallStack, IN UINTN SysCallStack,
IN VOID *CoreStack, IN VOID *CoreStack,
IN UINTN UserPageTable IN UINTN UserPageTable
); );

View File

@ -18,9 +18,9 @@ EFI_STATUS
EFIAPI EFIAPI
ArmCallRing3 ( ArmCallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN VOID *StackPointer, IN UINTN StackPointer,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN VOID *SysCallStack, IN UINTN SysCallStack,
IN VOID *CoreStack, IN VOID *CoreStack,
IN UINTN UserPageTable IN UINTN UserPageTable
); );

View File

@ -9,10 +9,8 @@
#include "DxeMain.h" #include "DxeMain.h"
VOID *gCoreSysCallStackTop; UINTN gCoreSysCallStackTop;
VOID *gCoreSysCallStackBase; UINTN gRing3CallStackTop;
VOID *gRing3CallStackTop;
VOID *gRing3CallStackBase;
VOID *gRing3EntryPoint; VOID *gRing3EntryPoint;
RING3_DATA *gRing3Data; RING3_DATA *gRing3Data;
VOID *gRing3Interfaces; VOID *gRing3Interfaces;
@ -48,8 +46,6 @@ InitializeRing3 (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
VOID *TopOfStack;
UINTN SizeOfStack;
EFI_PHYSICAL_ADDRESS Physical; EFI_PHYSICAL_ADDRESS Physical;
UINTN Index; UINTN Index;
EFI_CONFIGURATION_TABLE *Conf; EFI_CONFIGURATION_TABLE *Conf;
@ -157,42 +153,6 @@ InitializeRing3 (
EFI_MEMORY_XP | EFI_MEMORY_USER EFI_MEMORY_XP | EFI_MEMORY_USER
); );
SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE;
//
// Allocate 128KB for the Core SysCall Stack.
//
gCoreSysCallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE));
ASSERT (gCoreSysCallStackBase != NULL);
//
// Compute the top of the allocated stack. Pre-allocate a UINTN for safety.
//
TopOfStack = (VOID *)((UINTN)gCoreSysCallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT);
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
gCoreSysCallStackTop = TopOfStack;
SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP);
DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop));
//
// Allocate 128KB for the User Stack.
//
gRing3CallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE));
ASSERT (gRing3CallStackBase != NULL);
//
// Compute the top of the allocated stack. Pre-allocate a UINTN for safety.
//
TopOfStack = (VOID *)((UINTN)gRing3CallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT);
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
gRing3CallStackTop = TopOfStack;
SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER);
DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop));
InitializeMsr ( InitializeMsr (
gRing3Data->SystemTable.ConfigurationTable, gRing3Data->SystemTable.ConfigurationTable,
gRing3Data->SystemTable.NumberOfTableEntries gRing3Data->SystemTable.NumberOfTableEntries
@ -206,7 +166,11 @@ InitializeRing3 (
UINTN 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 UserStackSize
) )
{ {
UINTN UserPageTable; UINTN UserPageTable;
@ -222,7 +186,7 @@ InitializeUserPageTable (
MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize); MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize);
// //
// Map gRing3Data, gRing3Interfaces, gRing3CallStackBase, DxeRing3 // Map gRing3Data, gRing3Interfaces, UserStackBase, DxeRing3
// //
gCpu->SetUserMemoryAttributes ( gCpu->SetUserMemoryAttributes (
gCpu, gCpu,
@ -243,8 +207,8 @@ InitializeUserPageTable (
gCpu->SetUserMemoryAttributes ( gCpu->SetUserMemoryAttributes (
gCpu, gCpu,
UserPageTable, UserPageTable,
(UINTN)gRing3CallStackBase, UserStackBase,
EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, UserStackSize,
EFI_MEMORY_XP | EFI_MEMORY_USER EFI_MEMORY_XP | EFI_MEMORY_USER
); );
@ -264,7 +228,7 @@ InitializeUserPageTable (
} }
// //
// Map CoreBootServices, gCoreSysCallStackBase // Map CoreBootServices, SysCallStackBase
// //
gCpu->SetUserMemoryAttributes ( gCpu->SetUserMemoryAttributes (
gCpu, gCpu,
@ -277,8 +241,8 @@ InitializeUserPageTable (
gCpu->SetUserMemoryAttributes ( gCpu->SetUserMemoryAttributes (
gCpu, gCpu,
UserPageTable, UserPageTable,
(UINTN)gCoreSysCallStackBase, SysCallStackBase,
EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, SysCallStackSize,
EFI_MEMORY_XP EFI_MEMORY_XP
); );