diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index e4d87ee41a..09e9a37d1a 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -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 diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 94f8e78ef7..ff5414ec10 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -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; diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 9eb3b52184..f22009b8cb 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -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. diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm index 742063ce72..fc27a0bddc 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm @@ -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) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index bffea72d3e..b508682c4a 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -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); diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 50c89956f4..e40e26cb5d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -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, diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 90bcd4a0a0..4f3071bb41 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -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. diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index ba4298f736..4260cc1883 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -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 diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 56d6bee0fa..0cc71e4693 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -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