diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index dbd67f269d..8a843a4f7d 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2840,4 +2840,28 @@ CallRing3 ( ... ); +VOID +EFIAPI +DisableSMAP ( + VOID + ); + +VOID +EFIAPI +EnableSMAP ( + VOID + ); + +VOID +EFIAPI +DisableSMEP ( + VOID + ); + +VOID +EFIAPI +EnableSMEP ( + VOID + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index c84dc98fc5..20346631e5 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -30,6 +30,7 @@ extern BOOLEAN gBdsStarted; VOID *gCoreSysCallStackTop; VOID *gRing3CallStackTop; VOID *gRing3EntryPoint; +RING3_DATA *mRing3Data; // // This code is needed to build the Image handle for the DXE Core @@ -1725,9 +1726,17 @@ CoreStartImage ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gRing3EntryPoint = (VOID *)Image->EntryPoint; + mRing3Data = AllocateRing3CopyPages ((VOID *)Image->Info.SystemTable, sizeof (RING3_DATA)); - Image->Status = EFI_SUCCESS; + DisableSMAP (); + DisableSMEP (); + Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data); + + gRing3EntryPoint = mRing3Data->EntryPoint; + + mRing3Data->SystemTable.BootServices = mRing3Data->BootServices; + EnableSMEP (); + EnableSMAP (); } else { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1791,7 +1800,7 @@ CoreStartImage ( Image->Status = CallRing3 ( (VOID *)Image->EntryPoint, ImageHandle, - Image->Info.SystemTable + (EFI_SYSTEM_TABLE *)mRing3Data ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 7d3cc8beb0..3af5e62f99 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -13,15 +13,31 @@ VOID EFIAPI -DisableSMAP ( +DisableSMEP ( VOID - ); + ) +{ + IA32_CR4 Cr4; + + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMEP = 0; + + AsmWriteCr4 (Cr4.UintN); +} VOID EFIAPI -EnableSMAP ( +EnableSMEP ( VOID - ); + ) +{ + IA32_CR4 Cr4; + + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMEP = 1; + + AsmWriteCr4 (Cr4.UintN); +} EFI_STATUS EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c index d2e4b75816..55d971eda5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c @@ -6,6 +6,23 @@ **/ #include +#include + +EFI_STATUS +EFIAPI +Ring3Call ( + IN VOID *Dummy, + IN VOID *EntryPoint, + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +SysCall ( + IN UINT8 Type, + ... + ); EFI_STATUS EFIAPI @@ -14,5 +31,32 @@ Ring3EntryPoint ( IN EFI_SYSTEM_TABLE *SystemTable ) { + RING3_DATA *Ring3Data; + + Ring3Data = (RING3_DATA *)SystemTable; + + Ring3Data->EntryPoint = (VOID *)Ring3Call; + Ring3Data->BootServices = gBS; + return EFI_SUCCESS; } + +EFI_STATUS +EFIAPI +Ring3Call ( + IN VOID *Dummy, + IN VOID *EntryPoint, + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_IMAGE_ENTRY_POINT Function; + + Function = (EFI_IMAGE_ENTRY_POINT)EntryPoint; + + Function (ImageHandle, SystemTable); + + SysCall (SysCallReturnToCore); + + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf index f66a5def48..42f33e2d66 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf +++ b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf @@ -24,19 +24,13 @@ [Sources] Ring3Dxe.c -[Sources.X64] - X64/Ring3Dxe.nasm - [Packages] MdePkg/MdePkg.dec [LibraryClasses] BaseLib - DebugLib - -[Protocols] - -[Guids] + UefiBootServicesTableLib + UefiDriverEntryPoint [Depex] TRUE diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm deleted file mode 100644 index 410f6b41e6..0000000000 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm +++ /dev/null @@ -1,34 +0,0 @@ -;------------------------------------------------------------------------------ -; -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -; -;------------------------------------------------------------------------------ - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; _ModuleEntryPoint ( -; IN EFI_HANDLE ImageHandle, -; IN EFI_SYSTEM_TABLE *SystemTable -; ) -; -; (rcx) _ModuleEntryPoint - Used by SYSRET. -; (rdx) EntryPoint - Function address in User address space. -; (r8) Context1 - Parameter1 for entry point. -; (r9) Context2 - Parameter2 for entry point. -;------------------------------------------------------------------------------ -global ASM_PFX(_ModuleEntryPoint) -ASM_PFX(_ModuleEntryPoint): - mov rcx, r8 - mov r8, rdx - mov rdx, r9 - - call r8 - - mov r10, 0 - - syscall diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 730cb1050d..7a793bb885 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2108,6 +2108,12 @@ typedef struct { EFI_CONFIGURATION_TABLE *ConfigurationTable; } EFI_SYSTEM_TABLE; +typedef struct { + EFI_SYSTEM_TABLE SystemTable; + VOID *EntryPoint; + EFI_BOOT_SERVICES *BootServices; +} RING3_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