From 94017d956775139f03750bda3d17b6fb0345c182 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 29 Feb 2024 20:19:02 +0300 Subject: [PATCH] Ring3: Added PrepareRing3Interface(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 5 ++ MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 10 +++ .../Core/Dxe/DxeRing3/Ring3Protocols.c | 3 - MdeModulePkg/Core/Dxe/Image/Image.c | 53 ++++++++---- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 83 +++++++++++-------- 5 files changed, 102 insertions(+), 52 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 2219b0e678..973b2f2a45 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -115,6 +115,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define DEPEX_STACK_SIZE_INCREMENT 0x1000 #define USER_STACK_SIZE 0x20000 +#define RING3_INTERFACES_PAGES 20 typedef struct { EFI_GUID *ProtocolGuid; @@ -269,6 +270,10 @@ extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate; extern EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE gLoadModuleAtFixAddressConfigurationTable; extern BOOLEAN gLoadFixedAddressCodeMemoryReady; extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; + +extern RING3_DATA *gRing3Data; +extern VOID *gRing3Interfaces; + // // Service Initialization Functions // diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index b552fe77b1..d217b6d915 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -840,6 +840,16 @@ CoreExitBootServices ( // gRuntime->AtRuntime = TRUE; + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Interfaces, + RING3_INTERFACES_PAGES + ); + return Status; } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 2bd03a1a37..a3b082af82 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -7,9 +7,6 @@ #include "Ring3.h" -EFI_BLOCK_IO_PROTOCOL mCoreBlockIo; -EFI_DISK_IO_PROTOCOL mCoreDiskIo; - EFI_STATUS EFIAPI Ring3BlockIoReset ( diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 229a7673e5..069ffefa0c 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -30,7 +30,8 @@ extern BOOLEAN gBdsStarted; VOID *gCoreSysCallStackTop; VOID *gRing3CallStackTop; VOID *gRing3EntryPoint; -RING3_DATA *mRing3Data; +RING3_DATA *gRing3Data; +VOID *gRing3Interfaces; // // This code is needed to build the Image handle for the DXE Core @@ -1593,13 +1594,14 @@ AllocateRing3Copy ( return MemoryRing3; } -VOID +EFI_STATUS EFIAPI InitializeRing3 ( IN EFI_HANDLE ImageHandle, IN LOADED_IMAGE_PRIVATE_DATA *Image ) { + EFI_STATUS Status; VOID *BaseOfStack; VOID *TopOfStack; UINTN SizeOfStack; @@ -1616,18 +1618,39 @@ InitializeRing3 ( // // Set Ring3 EntryPoint and BootServices. // - mRing3Data = AllocateRing3Copy ( - (VOID *)Image->Info.SystemTable, - sizeof (RING3_DATA), - sizeof (EFI_SYSTEM_TABLE) - ); - ASSERT (mRing3Data != NULL); - - Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data); + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), + (EFI_PHYSICAL_ADDRESS *)&gRing3Data + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); + return Status; + } - gRing3EntryPoint = mRing3Data->EntryPoint; + CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); - mRing3Data->SystemTable.BootServices = mRing3Data->BootServices; + Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); + + gRing3EntryPoint = gRing3Data->EntryPoint; + + gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + RING3_INTERFACES_PAGES, + (EFI_PHYSICAL_ADDRESS *)&gRing3Interfaces + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + return Status; + } // // Forbid supervisor-mode accesses to any user-mode pages. @@ -1703,6 +1726,8 @@ InitializeRing3 ( Msr = (UINT64)(UINTN)CoreBootServices; AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); + + return Status; } /** @@ -1832,7 +1857,7 @@ CoreStartImage ( Image->Started = TRUE; if (Image->IsRing3EntryPoint) { - InitializeRing3 (ImageHandle, Image); + Image->Status = InitializeRing3 (ImageHandle, Image); } else if (Image->IsUserImage) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1841,7 +1866,7 @@ CoreStartImage ( 2, (VOID *)Image->EntryPoint, ImageHandle, - mRing3Data + gRing3Data ); } else { Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 2fa445ceab..b17f748676 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -10,6 +10,7 @@ EFI_DISK_IO_PROTOCOL *mCoreDiskIoProtocol; EFI_BLOCK_IO_PROTOCOL *mCoreBlockIoProtocol; +UINTN mRing3InterfacePointer = 0; EFI_STATUS EFIAPI @@ -20,6 +21,7 @@ CallInstallMultipleProtocolInterfaces ( IN VOID *Function ); +STATIC EFI_STATUS EFIAPI FindGuid ( @@ -79,24 +81,56 @@ FindGuid ( return EFI_SUCCESS; } -VOID +STATIC +VOID * EFIAPI -FixInterface ( - IN EFI_GUID *Guid, - IN OUT VOID *Interface +PrepareRing3Interface ( + IN EFI_GUID *Guid, + IN VOID *CoreInterface, + IN UINT32 CoreSize ) { + UINTN Ring3Limit; + VOID *Ring3Interface; EFI_BLOCK_IO_PROTOCOL *BlockIo; - if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Interface; + ASSERT (Guid != NULL); + ASSERT (CoreInterface != NULL); - BlockIo->Media = AllocateRing3Copy ( - BlockIo->Media, - sizeof (EFI_BLOCK_IO_MEDIA), - sizeof (EFI_BLOCK_IO_MEDIA) - ); + if (mRing3InterfacePointer == 0) { + mRing3InterfacePointer = (UINTN)gRing3Interfaces; } + + Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); + + ASSERT ((mRing3InterfacePointer + sizeof (EFI_GUID) + CoreSize) <= Ring3Limit); + + CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)Guid, sizeof (EFI_GUID)); + mRing3InterfacePointer += sizeof (EFI_GUID); + + Ring3Interface = (VOID *)mRing3InterfacePointer; + + CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize); + mRing3InterfacePointer += CoreSize; + + if (CompareGuid (Guid, &gEfiDiskIoProtocolGuid)) { + + mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)CoreInterface; + + } else if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { + ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit); + + mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)CoreInterface; + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; + + CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); + + BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer; + + mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); + } + + return Ring3Interface; } typedef struct { @@ -170,11 +204,7 @@ CallBootService ( DisableSMAP (); if (Interface != NULL) { - Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); - if (Interface == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } *(VOID **)CoreRbp->Argument3 = Interface; @@ -214,19 +244,7 @@ CallBootService ( DisableSMAP (); if (Interface != NULL) { - if (CompareGuid (CoreProtocol, &gEfiDiskIoProtocolGuid)) { - mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)Interface; - } else if (CompareGuid (CoreProtocol, &gEfiBlockIoProtocolGuid)) { - mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)Interface; - } - - Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); - if (Interface == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } - - FixInterface (CoreProtocol, Interface); + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } *(VOID **)CoreRbp->Argument3 = Interface; @@ -338,12 +356,7 @@ CallBootService ( DisableSMAP (); if (Interface != NULL) { - - Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); - if (Interface == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } *(VOID **)CoreRbp->Argument3 = Interface;