Ring3: Refactored out CoreRsp and UserStackTop.

This commit is contained in:
Mikhail Krichanov 2025-01-16 15:43:34 +03:00
parent ae0465017f
commit 2601648b32
12 changed files with 173 additions and 193 deletions

View File

@ -235,6 +235,16 @@ typedef struct {
UINTN UserStackTop; UINTN UserStackTop;
} LOADED_IMAGE_PRIVATE_DATA; } LOADED_IMAGE_PRIVATE_DATA;
typedef struct {
VOID *CoreWrapper;
VOID *UserSpaceDriver;
UINTN UserPageTable;
UINTN UserStackTop;
UINTN SysCallStackTop;
UINTN ReturnSP;
LIST_ENTRY Link;
} USER_SPACE_DRIVER;
#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE) CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE)
@ -279,6 +289,7 @@ extern VOID *gRing3Interfaces;
extern VOID *gRing3EntryPoint; extern VOID *gRing3EntryPoint;
extern UINTN gUserPageTable; extern UINTN gUserPageTable;
extern UINTN gCorePageTable; extern UINTN gCorePageTable;
extern LIST_ENTRY gUserSpaceDriversHead;
// //
// Service Initialization Functions // Service Initialization Functions
@ -2739,9 +2750,7 @@ EFI_STATUS
EFIAPI EFIAPI
CallBootService ( CallBootService (
IN UINT8 Type, IN UINT8 Type,
IN UINTN *UserArguments, IN UINTN *UserArguments
IN UINTN UserStackTop,
IN UINTN SysCallStackTop
); );
VOID VOID
@ -2759,10 +2768,9 @@ ForbidSupervisorAccessToUserMemory (
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
GoToRing3 ( GoToRing3 (
IN UINT8 Number, IN UINT8 Number,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN UINTN UserStackTop, IN USER_SPACE_DRIVER *UserDriver,
IN UINTN SysCallStackTop,
... ...
); );

View File

@ -1642,6 +1642,7 @@ CoreStartImage (
UINTN SetJumpFlag; UINTN SetJumpFlag;
EFI_HANDLE Handle; EFI_HANDLE Handle;
UINT64 Attributes; UINT64 Attributes;
USER_SPACE_DRIVER *UserDriver;
Handle = ImageHandle; Handle = ImageHandle;
@ -1743,11 +1744,19 @@ CoreStartImage (
gUserPageTable = Image->UserPageTable; gUserPageTable = Image->UserPageTable;
UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
UserDriver->CoreWrapper = NULL;
UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint;
UserDriver->UserPageTable = Image->UserPageTable;
UserDriver->UserStackTop = Image->UserStackTop;
UserDriver->SysCallStackTop = Image->SysCallStackTop;
InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link);
Image->Status = GoToRing3 ( Image->Status = GoToRing3 (
2, 2,
(VOID *)Image->EntryPoint, (VOID *)Image->EntryPoint,
Image->UserStackTop, UserDriver,
Image->SysCallStackTop,
ImageHandle, ImageHandle,
gRing3Data gRing3Data
); );

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. // Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause // SPDX-License-Identifier: BSD-3-Clause
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -62,14 +62,15 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// CallRing3 ( // CallRing3 (
// IN RING3_CALL_DATA *Data, // IN RING3_CALL_DATA *Data,
// IN UINTN UserStackTop, // IN UINTN UserStackTop,
// IN UINTN SysCallStackTop // IN UINTN SysCallStackTop,
// IN UINTN *ReturnSP
// ); // );
// //
// (x0) Data // (x0) Data
// (x1) UserStackTop // (x1) UserStackTop
// (x2) gRing3EntryPoint // (x2) gRing3EntryPoint
// (x3) SysCallStackTop // (x3) SysCallStackTop
// (x4) &CoreSp // (x4) ReturnSP
// (x5) gUserPageTable // (x5) gUserPageTable
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3) ASM_FUNC(ArmCallRing3)
@ -121,13 +122,14 @@ ASM_FUNC_ALIGN(SysCallEnd, 4096)
// VOID // VOID
// EFIAPI // EFIAPI
// ReturnToCore ( // ReturnToCore (
// IN EFI_STATUS Status // IN EFI_STATUS Status,
// IN UINTN ReturnSP
// ); // );
// //
// (x0) Status // (x0) Status
// (x1) mCoreSp // (x1) ReturnSP
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmReturnToCore) ASM_FUNC(ReturnToCore)
// Switch to Core Stack. // Switch to Core Stack.
mov sp, x1 mov sp, x1
// Restore registers and Stack. // Restore registers and Stack.

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved. Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause SPDX-License-Identifier: BSD-3-Clause
**/ **/
@ -12,8 +12,6 @@
#include "DxeMain.h" #include "DxeMain.h"
STATIC UINTN mCoreSp;
STATIC UINTN mUserStackTop;
STATIC UINTN mSysCallStackTop; STATIC UINTN mSysCallStackTop;
UINTN gUserPageTable; UINTN gUserPageTable;
@ -24,26 +22,10 @@ ArmCallRing3 (
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN UINTN SysCallStackTop, IN UINTN SysCallStackTop,
IN VOID *CoreStack, IN UINTN *ReturnSP,
IN UINTN UserPageTable IN UINTN UserPageTable
); );
VOID
EFIAPI
ArmReturnToCore (
IN EFI_STATUS Status,
IN UINTN CoreSp
);
VOID
EFIAPI
ReturnToCore (
IN EFI_STATUS Status
)
{
ArmReturnToCore (Status, mCoreSp);
}
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -74,9 +56,7 @@ SysCallBootService (
Status = CallBootService ( Status = CallBootService (
Type, Type,
(UINTN *)((UINTN)Physical + sizeof (UINTN)), (UINTN *)((UINTN)Physical + sizeof (UINTN))
mUserStackTop,
mSysCallStackTop
); );
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)));
@ -172,10 +152,10 @@ EFIAPI
CallRing3 ( CallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN UINTN SysCallStackTop IN UINTN SysCallStackTop,
IN UINTN *ReturnSP
) )
{ {
mUserStackTop = UserStackTop;
mSysCallStackTop = SysCallStackTop; mSysCallStackTop = SysCallStackTop;
return ArmCallRing3 ( return ArmCallRing3 (
@ -183,7 +163,7 @@ CallRing3 (
UserStackTop, UserStackTop,
gRing3EntryPoint, gRing3EntryPoint,
SysCallStackTop, SysCallStackTop,
&mCoreSp, ReturnSP,
gUserPageTable gUserPageTable
); );
} }

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. // Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause // SPDX-License-Identifier: BSD-3-Clause
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -58,7 +58,8 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// CallRing3 ( // CallRing3 (
// IN RING3_CALL_DATA *Data, // IN RING3_CALL_DATA *Data,
// IN UINTN UserStackTop, // IN UINTN UserStackTop,
// IN UINTN SysCallStackTop // IN UINTN SysCallStackTop,
// IN UINTN *ReturnSP
// ); // );
// //
// (r0) Data // (r0) Data
@ -66,12 +67,12 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
// (r2) gRing3EntryPoint // (r2) gRing3EntryPoint
// (r3) SysCallStackTop // (r3) SysCallStackTop
// //
// (On Core Stack) &CoreSp, gUserPageTable // (On Core Stack) ReturnSP, gUserPageTable
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmCallRing3) ASM_FUNC(ArmCallRing3)
// Save registers. // Save registers.
push {R4-R12, LR} push {R4-R12, LR}
// R6 is &CoreSp // R6 is ReturnSP
ldr R6, [SP, #0x28] ldr R6, [SP, #0x28]
// R7 is gUserPageTable // R7 is gUserPageTable
ldr R7, [SP, #0x2C] ldr R7, [SP, #0x2C]
@ -118,13 +119,14 @@ ASM_FUNC_ALIGN(SysCallEnd, 4096)
// VOID // VOID
// EFIAPI // EFIAPI
// ReturnToCore ( // ReturnToCore (
// IN EFI_STATUS Status // IN EFI_STATUS Status,
// IN UINTN ReturnSP
// ); // );
// //
// (r0) Status // (r0) Status
// (r1) mCoreSp // (r1) ReturnSP
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ASM_FUNC(ArmReturnToCore) ASM_FUNC(ReturnToCore)
// Switch to Core Stack. // Switch to Core Stack.
mov SP, R1 mov SP, R1

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved. Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause SPDX-License-Identifier: BSD-3-Clause
**/ **/
@ -11,8 +11,6 @@
#include "DxeMain.h" #include "DxeMain.h"
STATIC UINTN mCoreSp;
STATIC UINTN mUserStackTop;
STATIC UINTN mSysCallStackTop; STATIC UINTN mSysCallStackTop;
UINTN gUserPageTable; UINTN gUserPageTable;
@ -23,26 +21,10 @@ ArmCallRing3 (
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN UINTN SysCallStackTop, IN UINTN SysCallStackTop,
IN VOID *CoreStack, IN UINTN *ReturnSP,
IN UINTN UserPageTable IN UINTN UserPageTable
); );
VOID
EFIAPI
ArmReturnToCore (
IN EFI_STATUS Status,
IN UINTN CoreSp
);
VOID
EFIAPI
ReturnToCore (
IN EFI_STATUS Status
)
{
ArmReturnToCore (Status, mCoreSp);
}
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -80,9 +62,7 @@ SysCallBootService (
Status = CallBootService ( Status = CallBootService (
Type, Type,
(UINTN *)((UINTN)Physical + sizeof (UINTN)), (UINTN *)((UINTN)Physical + sizeof (UINTN))
mUserStackTop,
mSysCallStackTop
); );
// //
// TODO: Fix memory leak for ReturnToCore(). // TODO: Fix memory leak for ReturnToCore().
@ -167,10 +147,10 @@ EFIAPI
CallRing3 ( CallRing3 (
IN RING3_CALL_DATA *Data, IN RING3_CALL_DATA *Data,
IN UINTN UserStackTop, IN UINTN UserStackTop,
IN UINTN SysCallStackTop IN UINTN SysCallStackTop,
IN UINTN *ReturnSP
) )
{ {
mUserStackTop = UserStackTop;
mSysCallStackTop = SysCallStackTop; mSysCallStackTop = SysCallStackTop;
return ArmCallRing3 ( return ArmCallRing3 (
@ -178,7 +158,7 @@ CallRing3 (
UserStackTop, UserStackTop,
gRing3EntryPoint, gRing3EntryPoint,
SysCallStackTop, SysCallStackTop,
&mCoreSp, ReturnSP,
gUserPageTable gUserPageTable
); );
} }

View File

@ -68,7 +68,8 @@ CallInstallMultipleProtocolInterfaces (
VOID VOID
EFIAPI EFIAPI
ReturnToCore ( ReturnToCore (
IN EFI_STATUS Status IN EFI_STATUS Status,
IN UINTN ReturnSP
); );
VOID VOID
@ -304,13 +305,32 @@ CopyUserArguments (
return Arguments; return Arguments;
} }
STATIC
USER_SPACE_DRIVER *
EFIAPI
FindUserInfo (
VOID
)
{
LIST_ENTRY *Link;
USER_SPACE_DRIVER *UserDriver;
for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) {
UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link);
if ((UserDriver->UserPageTable == gUserPageTable) && (UserDriver->ReturnSP != 0)) {
return UserDriver;
}
}
return NULL;
}
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
CallBootService ( CallBootService (
IN UINT8 Type, IN UINT8 Type,
IN UINTN *UserArguments, IN UINTN *UserArguments
IN UINTN UserStackTop,
IN UINTN SysCallStackTop
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -329,6 +349,7 @@ CallBootService (
UINT32 PagesNumber; UINT32 PagesNumber;
EFI_PHYSICAL_ADDRESS Ring3Pages; EFI_PHYSICAL_ADDRESS Ring3Pages;
USER_SPACE_DRIVER *UserDriver; USER_SPACE_DRIVER *UserDriver;
USER_SPACE_DRIVER *NewDriver;
UINTN *Arguments; UINTN *Arguments;
EFI_PHYSICAL_ADDRESS PhysAddr; EFI_PHYSICAL_ADDRESS PhysAddr;
@ -350,9 +371,11 @@ CallBootService (
switch (Type) { switch (Type) {
case SysCallReturnToCore: case SysCallReturnToCore:
Arguments = CopyUserArguments (1, UserArguments); Arguments = CopyUserArguments (1, UserArguments);
UserDriver = FindUserInfo ();
ASSERT (UserDriver != NULL);
ReturnToCore (Arguments[1]); ReturnToCore (Arguments[1], UserDriver->ReturnSP);
break; break;
case SysCallLocateProtocol: case SysCallLocateProtocol:
// //
@ -496,17 +519,21 @@ CallBootService (
ASSERT ((Attributes & EFI_MEMORY_USER) != 0); ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]);
UserDriver = FindUserInfo ();
ASSERT (UserDriver != NULL);
// //
// TODO: Check everywhere that Allocated != NULL // TODO: Check everywhere that Allocated != NULL
// //
UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
UserDriver->CoreWrapper = CoreArgList[Index + 1]; NewDriver->CoreWrapper = CoreArgList[Index + 1];
UserDriver->UserSpaceDriver = UserArgList[Index + 1]; NewDriver->UserSpaceDriver = UserArgList[Index + 1];
UserDriver->UserPageTable = gUserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
UserDriver->UserStackTop = UserStackTop; NewDriver->UserStackTop = UserDriver->UserStackTop;
UserDriver->SysCallStackTop = SysCallStackTop; NewDriver->SysCallStackTop = UserDriver->SysCallStackTop;
NewDriver->ReturnSP = 0;
InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link);
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0); ASSERT ((Attributes & EFI_MEMORY_USER) != 0);

View File

@ -1,6 +1,6 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; ;
; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. ; Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
; SPDX-License-Identifier: BSD-3-Clause ; SPDX-License-Identifier: BSD-3-Clause
; ;
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
@ -133,8 +133,6 @@ ASM_PFX(CoreBootServices):
; Prepare CallBootService arguments. ; Prepare CallBootService arguments.
mov ebp, esp mov ebp, esp
push dword [ASM_PFX(SysCallStackTop)]
push dword [ASM_PFX(UserStackTop)]
add edx, 4 ; User Arguments[] add edx, 4 ; User Arguments[]
push edx push edx
push ecx ; Type push ecx ; Type
@ -168,10 +166,11 @@ ASM_PFX(CoreBootServices):
; CallRing3 ( ; CallRing3 (
; IN RING3_CALL_DATA *Data, ; IN RING3_CALL_DATA *Data,
; IN UINTN UserStackTop, ; IN UINTN UserStackTop,
; IN UINTN SysCallStackTop ; IN UINTN SysCallStackTop,
; IN UINTN *ReturnSP
; ); ; );
; ;
; (On User Stack) Data, UserStackTop, SysCallStackTop ; (On User Stack) Data, UserStackTop, SysCallStackTop, ReturnSP
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
global ASM_PFX(CallRing3) global ASM_PFX(CallRing3)
ASM_PFX(CallRing3): ASM_PFX(CallRing3):
@ -183,10 +182,9 @@ ASM_PFX(CallRing3):
push esi push esi
; Save Core Stack pointer. ; Save Core Stack pointer.
mov [ASM_PFX(CoreEsp)], esp mov ebx, [esp + 4 * 8] ; ReturnSP
mov [ebx], esp
mov ebx, [esp + 4 * 6]
mov [ASM_PFX(UserStackTop)], ebx
mov ebx, [esp + 4 * 7] mov ebx, [esp + 4 * 7]
mov [ASM_PFX(SysCallStackTop)], ebx mov [ASM_PFX(SysCallStackTop)], ebx
mov edx, 0 mov edx, 0
@ -197,7 +195,7 @@ ASM_PFX(CallRing3):
SetRing3DataSegmentSelectors SetRing3DataSegmentSelectors
; Prepare SYSEXIT arguments. ; Prepare SYSEXIT arguments.
mov ecx, [ASM_PFX(UserStackTop)] mov ecx, [esp + 4 * 6] ; UserStackTop
mov edx, [ASM_PFX(gRing3EntryPoint)] mov edx, [ASM_PFX(gRing3EntryPoint)]
mov eax, [esp + 4 * 5] ; Data mov eax, [esp + 4 * 5] ; Data
@ -219,14 +217,14 @@ ASM_PFX(SysCallEnd):
; VOID ; VOID
; EFIAPI ; EFIAPI
; ReturnToCore ( ; ReturnToCore (
; IN EFI_STATUS Status ; IN EFI_STATUS Status,
; IN UINTN ReturnSP
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
global ASM_PFX(ReturnToCore) global ASM_PFX(ReturnToCore)
ASM_PFX(ReturnToCore): ASM_PFX(ReturnToCore):
mov eax, [esp + 4] mov eax, [esp + 4] ; Status
mov esp, [esp + 4*2] ; ReturnSP
mov esp, [ASM_PFX(CoreEsp)]
pop esi pop esi
pop edi pop edi
pop ebp pop ebp
@ -247,11 +245,5 @@ ASM_PFX(gUserPageTable):
resd 1 resd 1
ALIGN 4096 ALIGN 4096
ASM_PFX(CoreEsp):
resd 1
ASM_PFX(UserStackTop):
resd 1
ASM_PFX(SysCallStackTop): ASM_PFX(SysCallStackTop):
resd 1 resd 1

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved. Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause SPDX-License-Identifier: BSD-3-Clause
**/ **/

View File

@ -8,23 +8,23 @@
#include "DxeMain.h" #include "DxeMain.h"
#include "SupportedProtocols.h" #include "SupportedProtocols.h"
LIST_ENTRY mUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (mUserSpaceDriversHead); LIST_ENTRY gUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (gUserSpaceDriversHead);
EFI_STATUS 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 IN UINTN SysCallStackTop,
IN UINTN *ReturnSP
); );
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
GoToRing3 ( GoToRing3 (
IN UINT8 Number, IN UINT8 Number,
IN VOID *EntryPoint, IN VOID *EntryPoint,
IN UINTN UserStackTop, IN USER_SPACE_DRIVER *UserDriver,
IN UINTN SysCallStackTop,
... ...
) )
{ {
@ -53,16 +53,28 @@ GoToRing3 (
Input->NumberOfArguments = Number; Input->NumberOfArguments = Number;
Input->EntryPoint = EntryPoint; Input->EntryPoint = EntryPoint;
VA_START (Marker, SysCallStackTop); VA_START (Marker, UserDriver);
for (Index = 0; Index < Number; ++Index) { for (Index = 0; Index < Number; ++Index) {
Input->Arguments[Index] = VA_ARG (Marker, UINTN); Input->Arguments[Index] = VA_ARG (Marker, UINTN);
} }
VA_END (Marker); VA_END (Marker);
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
//
Status = CallRing3 (Input, UserStackTop, SysCallStackTop); // TODO: Get(),Set() for old SysCallStackTop.
//
//
// TODO: Allocate new stacks (only for EFI_FILE_PROTOCOL instances?),
// because UserDriver can be interrupted and interrupt handler may call the same UserDriver again.
//
Status = CallRing3 (
Input,
UserDriver->UserStackTop,
UserDriver->SysCallStackTop,
&UserDriver->ReturnSP
);
CoreFreePages (Ring3Pages, PagesNumber); CoreFreePages (Ring3Pages, PagesNumber);
UserDriver->ReturnSP = 0;
return Status; return Status;
} }
@ -77,7 +89,7 @@ FindUserSpaceDriver (
LIST_ENTRY *Link; LIST_ENTRY *Link;
USER_SPACE_DRIVER *UserDriver; USER_SPACE_DRIVER *UserDriver;
for (Link = mUserSpaceDriversHead.ForwardLink; Link != &mUserSpaceDriversHead; Link = Link->ForwardLink) { for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) {
UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link);
if (UserDriver->CoreWrapper == CoreWrapper) { if (UserDriver->CoreWrapper == CoreWrapper) {
@ -113,8 +125,7 @@ CoreDriverBindingSupported (
Status = GoToRing3 ( Status = GoToRing3 (
3, 3,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
ControllerHandle, ControllerHandle,
RemainingDevicePath RemainingDevicePath
@ -147,8 +158,7 @@ CoreDriverBindingStart (
Status = GoToRing3 ( Status = GoToRing3 (
3, 3,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
ControllerHandle, ControllerHandle,
RemainingDevicePath RemainingDevicePath
@ -182,8 +192,7 @@ CoreDriverBindingStop (
Status = GoToRing3 ( Status = GoToRing3 (
4, 4,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
ControllerHandle, ControllerHandle,
NumberOfChildren, NumberOfChildren,
@ -216,8 +225,7 @@ CoreFileClose (
Status = GoToRing3 ( Status = GoToRing3 (
1, 1,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This This
); );
@ -293,8 +301,7 @@ CoreFileRead (
Status = GoToRing3 ( Status = GoToRing3 (
3, 3,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Ring3BufferSize, Ring3BufferSize,
Ring3Buffer Ring3Buffer
@ -349,8 +356,7 @@ CoreFileSetPosition (
return GoToRing3 ( return GoToRing3 (
2, 2,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Position Position
); );
@ -361,8 +367,7 @@ CoreFileSetPosition (
return GoToRing3 ( return GoToRing3 (
3, 3,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Position Position
); );
@ -374,10 +379,11 @@ CoreFileSetPosition (
return GoToRing3 ( return GoToRing3 (
4, 4,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Position NULL,
(UINT32)Position,
(UINT32)(Position >> 32)
); );
#endif #endif
@ -423,8 +429,7 @@ CoreFileGetPosition (
Status = GoToRing3 ( Status = GoToRing3 (
2, 2,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Ring3Position Ring3Position
); );
@ -504,8 +509,7 @@ CoreFileGetInfo (
Status = GoToRing3 ( Status = GoToRing3 (
4, 4,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Ring3InformationType, Ring3InformationType,
Ring3BufferSize, Ring3BufferSize,
@ -660,8 +664,7 @@ CoreFileOpen (
Status = GoToRing3 ( Status = GoToRing3 (
5, 5,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Ring3NewHandle, Ring3NewHandle,
Ring3FileName, Ring3FileName,
@ -675,8 +678,7 @@ CoreFileOpen (
Status = GoToRing3 ( Status = GoToRing3 (
7, 7,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Ring3NewHandle, Ring3NewHandle,
Ring3FileName, Ring3FileName,
@ -693,13 +695,15 @@ CoreFileOpen (
Status = GoToRing3 ( Status = GoToRing3 (
8, 8,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Ring3NewHandle, Ring3NewHandle,
Ring3FileName, Ring3FileName,
OpenMode, NULL,
Attributes (UINT32)OpenMode,
(UINT32)(OpenMode >> 32),
(UINT32)Attributes,
(UINT32)(Attributes >> 32)
); );
#endif #endif
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -718,10 +722,6 @@ CoreFileOpen (
NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
NewDriver->CoreWrapper = NewFile; NewDriver->CoreWrapper = NewFile;
NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
//
// TODO: Allocate new stacks, because UserDriver can be interrupted
// and interrupt handler may call the same UserDriver again.
//
NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->UserStackTop = UserDriver->UserStackTop;
NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; NewDriver->SysCallStackTop = UserDriver->SysCallStackTop;
@ -730,7 +730,7 @@ CoreFileOpen (
NewFile->Revision = (*Ring3NewHandle)->Revision; NewFile->Revision = (*Ring3NewHandle)->Revision;
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
InsertTailList (&mUserSpaceDriversHead, &NewDriver->Link); InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link);
NewFile->Open = CoreFileOpen; NewFile->Open = CoreFileOpen;
NewFile->Close = CoreFileClose; NewFile->Close = CoreFileClose;
@ -798,8 +798,7 @@ CoreOpenVolume (
Status = GoToRing3 ( Status = GoToRing3 (
2, 2,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
Ring3Root Ring3Root
); );
@ -827,7 +826,7 @@ CoreOpenVolume (
File->Revision = (*Ring3Root)->Revision; File->Revision = (*Ring3Root)->Revision;
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
InsertTailList (&mUserSpaceDriversHead, &NewDriver->Link); InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link);
File->Open = CoreFileOpen; File->Open = CoreFileOpen;
File->Close = CoreFileClose; File->Close = CoreFileClose;
@ -893,8 +892,7 @@ CoreUnicodeCollationStriColl (
Status = GoToRing3 ( Status = GoToRing3 (
3, 3,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
(UINTN)UserMem, (UINTN)UserMem,
(UINTN)UserMem + Size1 (UINTN)UserMem + Size1
@ -947,8 +945,7 @@ CoreUnicodeCollationMetaiMatch (
Status = GoToRing3 ( Status = GoToRing3 (
3, 3,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
(UINTN)UserMem, (UINTN)UserMem,
(UINTN)UserMem + Size1 (UINTN)UserMem + Size1
@ -997,8 +994,7 @@ CoreUnicodeCollationStrLwr (
Status = GoToRing3 ( Status = GoToRing3 (
2, 2,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
(UINTN)UserMem (UINTN)UserMem
); );
@ -1048,8 +1044,7 @@ CoreUnicodeCollationStrUpr (
Status = GoToRing3 ( Status = GoToRing3 (
2, 2,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
(UINTN)UserMem (UINTN)UserMem
); );
@ -1098,8 +1093,7 @@ CoreUnicodeCollationFatToStr (
Status = GoToRing3 ( Status = GoToRing3 (
4, 4,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
FatSize, FatSize,
(UINTN)UserMem, (UINTN)UserMem,
@ -1153,8 +1147,7 @@ CoreUnicodeCollationStrToFat (
Status = GoToRing3 ( Status = GoToRing3 (
4, 4,
EntryPoint, EntryPoint,
UserDriver->UserStackTop, UserDriver,
UserDriver->SysCallStackTop,
This, This,
(UINTN)UserMem, (UINTN)UserMem,
FatSize, FatSize,

View File

@ -11,17 +11,6 @@
#include <Protocol/DiskIo.h> #include <Protocol/DiskIo.h>
#include <Protocol/UnicodeCollation.h> #include <Protocol/UnicodeCollation.h>
typedef struct {
VOID *CoreWrapper;
VOID *UserSpaceDriver;
UINTN UserPageTable;
UINTN UserStackTop;
UINTN SysCallStackTop;
LIST_ENTRY Link;
} USER_SPACE_DRIVER;
extern LIST_ENTRY mUserSpaceDriversHead;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
CoreDriverBindingSupported ( CoreDriverBindingSupported (

View File

@ -1,6 +1,6 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; ;
; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. ; Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved.
; SPDX-License-Identifier: BSD-3-Clause ; SPDX-License-Identifier: BSD-3-Clause
; ;
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
@ -162,8 +162,6 @@ ASM_PFX(CoreBootServices):
mov rcx, r10 ; Type mov rcx, r10 ; Type
mov rdx, [rbp + 8*3] mov rdx, [rbp + 8*3]
add rdx, 8 ; User Arguments[] add rdx, 8 ; User Arguments[]
mov r8, [ASM_PFX(UserStackTop)]
mov r9, [ASM_PFX(SysCallStackTop)]
sti sti
call ASM_PFX(CallBootService) call ASM_PFX(CallBootService)
@ -175,7 +173,7 @@ ASM_PFX(CoreBootServices):
pop rax pop rax
; Step over NOOPT buffer. ; Step over NOOPT buffer.
add rsp, 8*4 mov rsp, rbp
; Prepare SYSRET arguments. ; Prepare SYSRET arguments.
pop r11 pop r11
@ -197,12 +195,14 @@ o64 sysret
; CallRing3 ( ; CallRing3 (
; IN RING3_CALL_DATA *Data, ; IN RING3_CALL_DATA *Data,
; IN UINTN UserStackTop, ; IN UINTN UserStackTop,
; IN UINTN SysCallStackTop ; IN UINTN SysCallStackTop,
; IN UINTN *ReturnSP
; ); ; );
; ;
; (rcx) Data ; (rcx) Data
; (rdx) UserStackTop ; (rdx) UserStackTop
; (r8) SysCallStackTop ; (r8) SysCallStackTop
; (r9) ReturnSP
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
global ASM_PFX(CallRing3) global ASM_PFX(CallRing3)
ASM_PFX(CallRing3): ASM_PFX(CallRing3):
@ -220,10 +220,10 @@ ASM_PFX(CallRing3):
push r15 push r15
; Save Core Stack pointer. ; Save Core Stack pointer.
mov [ASM_PFX(CoreRsp)], rsp mov [r9], rsp
; Save input Arguments. ; Save input Arguments.
mov [ASM_PFX(UserStackTop)], rdx mov rbx, rdx
mov [ASM_PFX(SysCallStackTop)], r8 mov [ASM_PFX(SysCallStackTop)], r8
mov r10, rcx mov r10, rcx
@ -234,7 +234,7 @@ ASM_PFX(CallRing3):
mov rcx, [ASM_PFX(gRing3EntryPoint)] mov rcx, [ASM_PFX(gRing3EntryPoint)]
; Switch to User Stack. ; Switch to User Stack.
mov rsp, [ASM_PFX(UserStackTop)] mov rsp, rbx
mov rbp, rsp mov rbp, rsp
mov r8, [ASM_PFX(gUserPageTable)] mov r8, [ASM_PFX(gUserPageTable)]
@ -250,12 +250,16 @@ ASM_PFX(SysCallEnd):
; VOID ; VOID
; EFIAPI ; EFIAPI
; ReturnToCore ( ; ReturnToCore (
; IN EFI_STATUS Status ; IN EFI_STATUS Status,
; IN UINTN ReturnSP
; ); ; );
;
; (rcx) Status
; (rdx) ReturnSP
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
global ASM_PFX(ReturnToCore) global ASM_PFX(ReturnToCore)
ASM_PFX(ReturnToCore): ASM_PFX(ReturnToCore):
mov rsp, [ASM_PFX(CoreRsp)] mov rsp, rdx
pop r15 pop r15
pop r14 pop r14
pop r13 pop r13
@ -281,11 +285,5 @@ ASM_PFX(gUserPageTable):
resq 1 resq 1
ALIGN 4096 ALIGN 4096
ASM_PFX(CoreRsp):
resq 1
ASM_PFX(UserStackTop):
resq 1
ASM_PFX(SysCallStackTop): ASM_PFX(SysCallStackTop):
resq 1 resq 1