Ring3: Refactored CallRing3().

This commit is contained in:
Mikhail Krichanov 2024-02-15 18:42:55 +03:00
parent b08d7cbb16
commit fa60f3ab00
9 changed files with 174 additions and 41 deletions

View File

@ -2836,8 +2836,7 @@ CoreBootServices (
EFI_STATUS
EFIAPI
CallRing3 (
IN VOID *EntryPoint,
...
IN RING3_CALL_DATA *Data
);
VOID
@ -2852,4 +2851,12 @@ EnableSMAP (
VOID
);
EFI_STATUS
EFIAPI
GoToRing3 (
IN UINT8 Number,
IN VOID *EntryPoint,
...
);
#endif

View File

@ -64,29 +64,106 @@ EFI_BOOT_SERVICES mBootServices = {
(EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx
};
VOID
EFIAPI
Ring3EntryPoint (
IN RING3_CALL_DATA *Data
);
typedef
EFI_STATUS
(EFIAPI *FUNCTION_0)(
VOID
);
typedef
EFI_STATUS
(EFIAPI *FUNCTION_1)(
IN UINTN Argument1
);
typedef
EFI_STATUS
(EFIAPI *FUNCTION_2)(
IN UINTN Argument1,
IN UINTN Argument2
);
typedef
EFI_STATUS
(EFIAPI *FUNCTION_3)(
IN UINTN Argument1,
IN UINTN Argument2,
IN UINTN Argument3
);
typedef
EFI_STATUS
(EFIAPI *FUNCTION_4)(
IN UINTN Argument1,
IN UINTN Argument2,
IN UINTN Argument3,
IN UINTN Argument4
);
typedef
EFI_STATUS
(EFIAPI *FUNCTION_5)(
IN UINTN Argument1,
IN UINTN Argument2,
IN UINTN Argument3,
IN UINTN Argument4,
IN UINTN Argument5
);
VOID
EFIAPI
Ring3Call (
IN VOID *Dummy,
IN VOID *EntryPoint,
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
IN RING3_CALL_DATA *Data
)
{
EFI_IMAGE_ENTRY_POINT Function;
FUNCTION_0 Function0;
FUNCTION_1 Function1;
FUNCTION_2 Function2;
FUNCTION_3 Function3;
FUNCTION_4 Function4;
FUNCTION_5 Function5;
Function = (EFI_IMAGE_ENTRY_POINT)EntryPoint;
Function (ImageHandle, SystemTable);
switch (Data->NumberOfArguments) {
case 0:
Function0 = (FUNCTION_0)Data->EntryPoint;
Function0 ();
break;
case 1:
Function1 = (FUNCTION_1)Data->EntryPoint;
Function1 (Data->Arguments[0]);
break;
case 2:
Function2 = (FUNCTION_2)Data->EntryPoint;
Function2 (Data->Arguments[0], Data->Arguments[1]);
break;
case 3:
Function3 = (FUNCTION_3)Data->EntryPoint;
Function3 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2]);
break;
case 4:
Function4 = (FUNCTION_4)Data->EntryPoint;
Function4 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3]);
break;
case 5:
Function5 = (FUNCTION_5)Data->EntryPoint;
Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]);
break;
default:
break;
}
SysCall (SysCallReturnToCore);
return EFI_UNSUPPORTED;
}
EFI_STATUS
EFIAPI
Ring3EntryPoint (
Ring3Initialization (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
@ -95,7 +172,7 @@ Ring3EntryPoint (
Ring3Data = (RING3_DATA *)SystemTable;
Ring3Data->EntryPoint = (VOID *)Ring3Call;
Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint;
Ring3Data->BootServices = &mBootServices;
return EFI_SUCCESS;

View File

@ -13,7 +13,7 @@
FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = Ring3EntryPoint
ENTRY_POINT = Ring3Initialization
#
# The following information is for reference only and not required by the build tools.

View File

@ -3,8 +3,10 @@
; SPDX-License-Identifier: BSD-3-Clause
;------------------------------------------------------------------------------
DEFAULT REL
SECTION .text
extern ASM_PFX(Ring3Call)
DEFAULT REL
SECTION .text
;------------------------------------------------------------------------------
; EFI_STATUS
@ -24,3 +26,19 @@ ASM_PFX(SysCall):
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
ret
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; Ring3EntryPoint (
; IN RING3_CALL_DATA *Data
; );
;
; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3().
; (rdx) Data
;------------------------------------------------------------------------------
global ASM_PFX(Ring3EntryPoint)
ASM_PFX(Ring3EntryPoint):
mov rcx, rdx
call ASM_PFX(Ring3Call)

View File

@ -1838,10 +1838,11 @@ CoreStartImage (
EFI_MEMORY_XP | EFI_MEMORY_USER
);
Image->Status = CallRing3 (
Image->Status = GoToRing3 (
2,
(VOID *)Image->EntryPoint,
ImageHandle,
(EFI_SYSTEM_TABLE *)mRing3Data
mRing3Data
);
} else {
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);

View File

@ -11,12 +11,43 @@ EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported;
EFI_DRIVER_BINDING_START mUserDriverBindingStart;
EFI_DRIVER_BINDING_STOP mUserDriverBindingStop;
typedef enum {
UserDriverBindingSupported = 1,
UserDriverBindingStart = 2,
UserDriverBindingStop = 3,
UserCallMax
} USER_CALL_TYPE;
EFI_STATUS
EFIAPI
GoToRing3 (
IN UINT8 Number,
IN VOID *EntryPoint,
...
)
{
EFI_STATUS Status;
RING3_CALL_DATA *Input;
VA_LIST Marker;
UINTN Index;
DisableSMAP ();
Status = gBS->AllocatePool (
EfiRing3MemoryType,
sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN),
(VOID **)&Input
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate memory for Input data.\n"));
EnableSMAP ();
return Status;
}
Input->NumberOfArguments = Number;
Input->EntryPoint = EntryPoint;
VA_START (Marker, EntryPoint);
for (Index = 0; Index < Number; ++Index) {
Input->Arguments[Index] = VA_ARG (Marker, UINTN);
}
VA_END (Marker);
EnableSMAP ();
return CallRing3 (Input);
}
EFI_STATUS
EFIAPI
@ -26,7 +57,8 @@ CoreDriverBindingSupported (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
return CallRing3 (
return GoToRing3 (
3,
(VOID *)mUserDriverBindingSupported,
This,
ControllerHandle,
@ -42,7 +74,8 @@ CoreDriverBindingStart (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
return CallRing3 (
return GoToRing3 (
3,
(VOID *)mUserDriverBindingStart,
This,
ControllerHandle,
@ -59,7 +92,8 @@ CoreDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
return CallRing3 (
return GoToRing3 (
4,
(VOID *)mUserDriverBindingStop,
This,
ControllerHandle,

View File

@ -178,23 +178,16 @@ o64 sysret
; EFI_STATUS
; EFIAPI
; CallRing3 (
; IN VOID *EntryPoint,
; ...
; IN RING3_CALL_DATA *Data
; );
;
; (rcx) EntryPoint - Entry point in User address space.
; (rdx) Context1 - Parameter1 for entry point.
; (r8) Context2 - Parameter2 for entry point.
; (rcx) Data
;------------------------------------------------------------------------------
global ASM_PFX(CallRing3)
ASM_PFX(CallRing3):
; Save input Arguments.
push r12
push r13
push r14
mov r12, rcx
mov r13, rdx
mov r14, r8
; Extract User Data selector.
mov rcx, MSR_IA32_STAR
@ -213,14 +206,10 @@ ASM_PFX(CallRing3):
; Prepare SYSRET arguments.
mov rcx, [gRing3EntryPoint]
mov rdx, r12
mov r8, r13
mov r9, r14
pushfq
pop r11
; Restore stack and registers.
pop r14
pop r13
pop r12
; Save Core Stack pointers and switch to User Stack.

View File

@ -315,6 +315,7 @@
MdeModulePkg/Bus/Spi/SpiHc/SpiHcDxe.inf
MdeModulePkg/Bus/Spi/SpiHc/SpiHcSmm.inf
MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
MdeModulePkg/Core/Pei/PeiMain.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf

View File

@ -2115,6 +2115,12 @@ typedef struct {
EFI_BOOT_SERVICES *BootServices;
} RING3_DATA;
typedef struct {
UINT8 NumberOfArguments;
VOID *EntryPoint;
UINTN Arguments[];
} RING3_CALL_DATA;
/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including