Ring3: Refactored CallRing3().

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

View File

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

View File

@ -64,29 +64,106 @@ EFI_BOOT_SERVICES mBootServices = {
(EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx
}; };
VOID
EFIAPI
Ring3EntryPoint (
IN RING3_CALL_DATA *Data
);
typedef
EFI_STATUS 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 EFIAPI
Ring3Call ( Ring3Call (
IN VOID *Dummy, IN RING3_CALL_DATA *Data
IN VOID *EntryPoint,
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
) )
{ {
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; switch (Data->NumberOfArguments) {
case 0:
Function (ImageHandle, SystemTable); 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); SysCall (SysCallReturnToCore);
return EFI_UNSUPPORTED;
} }
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
Ring3EntryPoint ( Ring3Initialization (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable IN EFI_SYSTEM_TABLE *SystemTable
) )
@ -95,7 +172,7 @@ Ring3EntryPoint (
Ring3Data = (RING3_DATA *)SystemTable; Ring3Data = (RING3_DATA *)SystemTable;
Ring3Data->EntryPoint = (VOID *)Ring3Call; Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint;
Ring3Data->BootServices = &mBootServices; Ring3Data->BootServices = &mBootServices;
return EFI_SUCCESS; return EFI_SUCCESS;

View File

@ -13,7 +13,7 @@
FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B
MODULE_TYPE = DXE_DRIVER MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0 VERSION_STRING = 1.0
ENTRY_POINT = Ring3EntryPoint ENTRY_POINT = Ring3Initialization
# #
# The following information is for reference only and not required by the build tools. # 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 ; SPDX-License-Identifier: BSD-3-Clause
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
DEFAULT REL extern ASM_PFX(Ring3Call)
SECTION .text
DEFAULT REL
SECTION .text
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; EFI_STATUS ; EFI_STATUS
@ -24,3 +26,19 @@ ASM_PFX(SysCall):
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
ret 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 EFI_MEMORY_XP | EFI_MEMORY_USER
); );
Image->Status = CallRing3 ( Image->Status = GoToRing3 (
2,
(VOID *)Image->EntryPoint, (VOID *)Image->EntryPoint,
ImageHandle, ImageHandle,
(EFI_SYSTEM_TABLE *)mRing3Data mRing3Data
); );
} else { } else {
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); 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_START mUserDriverBindingStart;
EFI_DRIVER_BINDING_STOP mUserDriverBindingStop; EFI_DRIVER_BINDING_STOP mUserDriverBindingStop;
typedef enum { EFI_STATUS
UserDriverBindingSupported = 1, EFIAPI
UserDriverBindingStart = 2, GoToRing3 (
UserDriverBindingStop = 3, IN UINT8 Number,
UserCallMax IN VOID *EntryPoint,
} USER_CALL_TYPE; ...
)
{
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 EFI_STATUS
EFIAPI EFIAPI
@ -26,7 +57,8 @@ CoreDriverBindingSupported (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
) )
{ {
return CallRing3 ( return GoToRing3 (
3,
(VOID *)mUserDriverBindingSupported, (VOID *)mUserDriverBindingSupported,
This, This,
ControllerHandle, ControllerHandle,
@ -42,7 +74,8 @@ CoreDriverBindingStart (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
) )
{ {
return CallRing3 ( return GoToRing3 (
3,
(VOID *)mUserDriverBindingStart, (VOID *)mUserDriverBindingStart,
This, This,
ControllerHandle, ControllerHandle,
@ -59,7 +92,8 @@ CoreDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
) )
{ {
return CallRing3 ( return GoToRing3 (
4,
(VOID *)mUserDriverBindingStop, (VOID *)mUserDriverBindingStop,
This, This,
ControllerHandle, ControllerHandle,

View File

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

View File

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

View File

@ -2127,6 +2127,12 @@ typedef struct {
EFI_BOOT_SERVICES *BootServices; EFI_BOOT_SERVICES *BootServices;
} RING3_DATA; } 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 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 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including