From 9ef906f69501a0d2a075d6b9d1a9336b5bcc7306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 26 Mar 2023 22:36:45 +0200 Subject: [PATCH] MdePkg/UefiImageLib: Require callers to allocate aligned memory --- EmbeddedPkg/Library/PrePiLib/PrePiLib.c | 11 ++-- .../FspWrapperNotifyDxe.inf | 1 + .../FspWrapperNotifyDxe/LoadBelow4G.c | 34 +++++++----- MdeModulePkg/Core/Dxe/DxeMain.h | 1 + MdeModulePkg/Core/Dxe/Image/Image.c | 25 ++++----- MdeModulePkg/Core/Pei/Image/Image.c | 30 +++++----- MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 55 +++++++------------ MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 23 +++++--- .../BootScriptExecutorDxe.inf | 1 + .../BootScriptExecutorDxe/ScriptExecute.c | 38 ++++++------- .../BootScriptExecutorDxe/ScriptExecute.h | 1 + MdePkg/Include/Library/UefiImageLib.h | 24 +------- MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c | 36 ++---------- .../Library/BaseUefiImageLib/CommonSupport.c | 36 ------------ StandaloneMmPkg/Core/Dispatcher.c | 46 +++++----------- UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 14 ++--- 16 files changed, 133 insertions(+), 243 deletions(-) diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c index c456d20f98..a877c5c89b 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c +++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c @@ -36,17 +36,18 @@ LoadUefiImage ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; VOID *Buffer; UINT32 BufferSize; + UINT32 BufferAlignment; Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize); ASSERT_EFI_ERROR (Status); - Status = UefiImageLoaderGetDestinationSize (&ImageContext, &BufferSize); - ASSERT_EFI_ERROR (Status); + BufferSize = UefiImageGetImageSize (&ImageContext); + BufferAlignment = UefiImageGetSegmentAlignment (&ImageContext); // // Allocate Memory for the image // - Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES (BufferSize)); + Buffer = AllocateAlignedCodePages (EFI_SIZE_TO_PAGES (BufferSize), BufferAlignment); ASSERT (Buffer != 0); // @@ -55,8 +56,8 @@ LoadUefiImage ( Status = UefiImageLoadImageForExecution (&ImageContext, Buffer, BufferSize, NULL, 0); ASSERT_EFI_ERROR (Status); - *ImageAddress = (UINTN) UefiImageLoaderGetImageAddress (&ImageContext); - *ImageSize = UefiImageGetImageSize (&ImageContext); + *ImageAddress = (UINTN) Buffer; + *ImageSize = BufferSize; *EntryPoint = (UINTN) UefiImageLoaderGetImageEntryPoint (&ImageContext); return Status; diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf index 3a4aefcbde..37db0a5a21 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf @@ -45,6 +45,7 @@ PerformanceLib HobLib FspWrapperPlatformLib + MemoryAllocationLib [Protocols] gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c index bb0c5f2f53..1a1d052b4d 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -16,6 +16,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include +#include /** Relocate this image under 4G memory. @@ -37,10 +39,11 @@ RelocateImageUnder4GIfNeeded ( UINT8 *Buffer; UINTN BufferSize; EFI_HANDLE NewImageHandle; - UINT32 DestinationSize; + UINT32 ImageSize; + UINT32 ImageAlignment; UINTN Pages; EFI_PHYSICAL_ADDRESS FfsBuffer; - UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; VOID *Interface; // @@ -89,17 +92,18 @@ RelocateImageUnder4GIfNeeded ( // Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize); ASSERT_EFI_ERROR (Status); - Status = UefiImageLoaderGetDestinationSize (&ImageContext, &DestinationSize); - ASSERT_EFI_ERROR (Status); - Pages = EFI_SIZE_TO_PAGES (DestinationSize); + ImageSize = UefiImageGetImageSize (&ImageContext); + ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); + Pages = EFI_SIZE_TO_PAGES (ImageSize); FfsBuffer = 0xFFFFFFFF; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiBootServicesCode, - Pages, - &FfsBuffer - ); + Status = AllocateAlignedPagesEx ( + AllocateMaxAddress, + EfiBootServicesCode, + Pages, + ImageAlignment, + &FfsBuffer + ); ASSERT_EFI_ERROR (Status); // // Load and relocate the image to our new buffer @@ -107,7 +111,7 @@ RelocateImageUnder4GIfNeeded ( Status = UefiImageLoadImageForExecution ( &ImageContext, (VOID *) (UINTN) FfsBuffer, - DestinationSize, + ImageSize, NULL, 0 ); @@ -118,11 +122,11 @@ RelocateImageUnder4GIfNeeded ( // gBS->FreePool (Buffer); - DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", UefiImageLoaderGetImageAddress (&ImageContext), UefiImageLoaderGetImageEntryPoint (&ImageContext))); + DEBUG ((DEBUG_INFO, "Loading driver at 0x%08llx EntryPoint=0x%08x\n", FfsBuffer, UefiImageLoaderGetImageEntryPoint (&ImageContext))); Status = ((EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (&ImageContext)))(NewImageHandle, gST); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", UefiImageLoaderGetImageAddress (&ImageContext), Status)); - gBS->FreePages (FfsBuffer, Pages); + DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08llx start failed: %r\n", FfsBuffer, Status)); + FreeAlignedPages ((VOID *)(UINTN)FfsBuffer, Pages); } // diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 0cc936b691..4a20f9b6c5 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -77,6 +77,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include #include diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index aeaf3e4e97..cd67818517 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -8,8 +8,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "DxeMain.h" #include "Image.h" -#include "Library/UefiImageLib.h" -#include "Uefi/UefiBaseType.h" // // Module Globals @@ -514,11 +512,11 @@ CoreLoadPeImage ( EFI_STATUS Status; BOOLEAN DstBufAlocated; UINT32 Size; + UINT32 Alignment; EFI_MEMORY_TYPE ImageCodeMemoryType; EFI_MEMORY_TYPE ImageDataMemoryType; UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RelocationData; EFI_PHYSICAL_ADDRESS BufferAddress; - UINTN LoadAddress; UINT32 RelocDataSize; RelocationData = NULL; @@ -560,10 +558,8 @@ CoreLoadPeImage ( return EFI_UNSUPPORTED; } - Status = UefiImageLoaderGetDestinationSize (ImageContext, &Size); - if (RETURN_ERROR (Status)) { - return Status; - } + Size = UefiImageGetImageSize (ImageContext); + Alignment = UefiImageGetSegmentAlignment (ImageContext); BufferAddress = 0; // @@ -606,7 +602,7 @@ CoreLoadPeImage ( if (EFI_ERROR (Status)) { BufferAddress = UefiImageGetPreferredAddress (ImageContext); if ((BufferAddress >= 0x100000) || UefiImageGetRelocsStripped (ImageContext)) { - Status = CoreAllocatePages ( + Status = AllocatePagesEx ( AllocateAddress, ImageCodeMemoryType, Image->NumberOfPages, @@ -615,10 +611,11 @@ CoreLoadPeImage ( } if (EFI_ERROR (Status) && !UefiImageGetRelocsStripped (ImageContext)) { - Status = CoreAllocatePages ( + Status = AllocateAlignedPagesEx ( AllocateAnyPages, ImageCodeMemoryType, Image->NumberOfPages, + Alignment, &BufferAddress ); } @@ -703,8 +700,6 @@ CoreLoadPeImage ( goto Done; } - LoadAddress = UefiImageLoaderGetImageAddress (ImageContext); - // // Copy the machine type from the context to the image private data. // @@ -719,7 +714,7 @@ CoreLoadPeImage ( // Fill in the image information for the Loaded Image Protocol // Image->Type = UefiImageGetSubsystem (ImageContext); - Image->Info.ImageBase = (VOID *)(UINTN)LoadAddress; + Image->Info.ImageBase = (VOID *)(UINTN)BufferAddress; Image->Info.ImageSize = UefiImageGetImageSize (ImageContext); Image->Info.ImageCodeType = ImageCodeMemoryType; Image->Info.ImageDataType = ImageDataMemoryType; @@ -756,7 +751,7 @@ CoreLoadPeImage ( ASSERT_EFI_ERROR (Status); } if (!EFI_ERROR (Status)) { - Image->HiiData = (VOID *)(UINTN)(LoadAddress + Hiioff); + Image->HiiData = (VOID *)((UINTN)BufferAddress + Hiioff); } // @@ -769,7 +764,7 @@ CoreLoadPeImage ( DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading driver at 0x%11p EntryPoint=0x%11p \n", - (VOID *)(UINTN)LoadAddress, + (VOID *)(UINTN)BufferAddress, FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); Status = UefiImageGetModuleNameFromSymbolsPath ( @@ -798,7 +793,7 @@ Done: if (DstBufAlocated) { ZeroMem ((VOID *)(UINTN)BufferAddress, EFI_PAGES_TO_SIZE (Image->NumberOfPages)); - CoreFreePages (BufferAddress, Image->NumberOfPages); + FreeAlignedPages ((VOID *)(UINTN)BufferAddress, Image->NumberOfPages); Image->ImageBasePage = 0; } diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index 3d1a1e68b6..2afb2ffe32 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -169,8 +169,10 @@ LoadAndRelocateUefiImage ( ) { EFI_STATUS Status; + BOOLEAN Success; PEI_CORE_INSTANCE *Private; UINT32 DynamicImageSize; + UINT32 DynamicImageAlignment; BOOLEAN IsXipImage; EFI_STATUS ReturnStatus; BOOLEAN IsS3Boot; @@ -261,38 +263,38 @@ LoadAndRelocateUefiImage ( (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot))) ) { - Status = EFI_UNSUPPORTED; + Success = FALSE; if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { Status = GetUefiImageFixLoadingAssignedAddress(ImageContext, Private, &LoadAddress); if (!EFI_ERROR (Status)){ DynamicImageSize = UefiImageGetImageSize (ImageContext); - if (LoadAddress != UefiImageGetPreferredAddress (ImageContext)) { - Status = EFI_UNSUPPORTED; + Success = LoadAddress == UefiImageGetPreferredAddress (ImageContext); + + if (!Success) { DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n")); } } else { DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); } } - if (EFI_ERROR (Status)) { + + if (!Success) { // // Allocate more buffer to avoid buffer overflow. // - Status = UefiImageLoaderGetDestinationSize (ImageContext, &DynamicImageSize); - if (RETURN_ERROR (Status)) { - return Status; - } + DynamicImageSize = UefiImageGetImageSize (ImageContext); + DynamicImageAlignment = UefiImageGetSegmentAlignment (ImageContext); - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - EFI_SIZE_TO_PAGES (DynamicImageSize), - &LoadAddress - ); + LoadAddress = (UINTN)AllocateAlignedCodePages ( + EFI_SIZE_TO_PAGES (DynamicImageSize), + DynamicImageAlignment + ); + Success = LoadAddress != 0; } - if (!EFI_ERROR (Status)) { + if (Success) { LoadDynamically = TRUE; // // Load the image to our new buffer diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c index b72d365080..648371270d 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -274,8 +274,9 @@ SmmLoadImage ( EFI_STATUS Status; EFI_STATUS SecurityStatus; EFI_HANDLE DeviceHandle; - EFI_PHYSICAL_ADDRESS DstBuffer; + VOID *DstBuffer; UINT32 DstBufferSize; + UINT32 DstBufferAlignment; EFI_DEVICE_PATH_PROTOCOL *FilePath; EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath; EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; @@ -425,10 +426,8 @@ SmmLoadImage ( return EFI_UNSUPPORTED; } - Status = UefiImageLoaderGetDestinationSize (ImageContext, &DstBufferSize); - if (RETURN_ERROR (Status)) { - return Status; - } + DstBufferSize = UefiImageGetImageSize (ImageContext); + DstBufferAlignment = UefiImageGetSegmentAlignment (ImageContext); // // if Loading module at Fixed Address feature is enabled, then cut out a memory range started from TESG BASE // to hold the Smm driver code @@ -444,45 +443,33 @@ SmmLoadImage ( // following statements is to bypass SmmFreePages // PageCount = 0; - DstBuffer = LoadAddress; + DstBuffer = (VOID *)(UINTN)LoadAddress; } else { DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); // // allocate the memory to load the SMM driver // PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DstBufferSize); - DstBuffer = (UINTN)(-1); - Status = SmmAllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesCode, - PageCount, - &DstBuffer - ); - if (EFI_ERROR (Status)) { + DstBuffer = AllocateAlignedCodePages (PageCount, DstBufferAlignment); + if (DstBuffer == NULL) { if (Buffer != NULL) { gBS->FreePool (Buffer); } - return Status; + return EFI_OUT_OF_RESOURCES; } } } else { PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DstBufferSize); - DstBuffer = (UINTN)(-1); - Status = SmmAllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesCode, - PageCount, - &DstBuffer - ); - if (EFI_ERROR (Status)) { + DstBuffer = AllocateAlignedCodePages (PageCount, DstBufferAlignment); + if (DstBuffer == NULL) { if (Buffer != NULL) { gBS->FreePool (Buffer); } - return Status; + return EFI_OUT_OF_RESOURCES; } } @@ -491,7 +478,7 @@ SmmLoadImage ( // Status = UefiImageLoadImageForExecution ( ImageContext, - (VOID *) (UINTN) DstBuffer, + DstBuffer, DstBufferSize, NULL, 0 @@ -501,17 +488,15 @@ SmmLoadImage ( gBS->FreePool (Buffer); } - SmmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, PageCount); return Status; } - LoadAddress = UefiImageLoaderGetImageAddress (ImageContext); - // // Save Image EntryPoint in DriverEntry // DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); - DriverEntry->ImageBuffer = DstBuffer; + DriverEntry->ImageBuffer = (UINTN)DstBuffer; DriverEntry->NumberOfPage = PageCount; // @@ -523,7 +508,7 @@ SmmLoadImage ( gBS->FreePool (Buffer); } - SmmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, PageCount); return Status; } @@ -551,13 +536,13 @@ SmmLoadImage ( gBS->FreePool (Buffer); } - SmmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, PageCount); return Status; } CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath)); - DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)LoadAddress; + DriverEntry->LoadedImage->ImageBase = DstBuffer; DriverEntry->LoadedImage->ImageSize = UefiImageGetImageSize (ImageContext); DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode; DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData; @@ -572,13 +557,13 @@ SmmLoadImage ( } gBS->FreePool (DriverEntry->LoadedImage->FilePath); - SmmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, PageCount); return Status; } CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath)); - DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)LoadAddress; + DriverEntry->SmmLoadedImage.ImageBase = DstBuffer; DriverEntry->SmmLoadedImage.ImageSize = UefiImageGetImageSize (ImageContext); DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode; DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData; @@ -629,7 +614,7 @@ SmmLoadImage ( DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading SMM driver at 0x%11p EntryPoint=0x%11p ", - (VOID *)(UINTN)LoadAddress, + DstBuffer, FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); // diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c index 41ef2c1c05..b63968f7b2 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -977,6 +977,8 @@ ExecuteSmmCoreFromSmram ( VOID *SourceBuffer; UINTN SourceSize; UINT32 DestinationSize; + UINT32 DestinationAlignment; + UINT32 AlignSubtrahend; UINTN PageCount; EFI_IMAGE_ENTRY_POINT EntryPoint; EFI_PHYSICAL_ADDRESS LoadAddress; @@ -1012,13 +1014,8 @@ ExecuteSmmCoreFromSmram ( return EFI_UNSUPPORTED; } - Status = UefiImageLoaderGetDestinationSize ( - &gSmmCorePrivate->PiSmmCoreImageContext, - &DestinationSize - ); - if (RETURN_ERROR (Status)) { - return Status; - } + DestinationSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext); + DestinationAlignment = UefiImageGetSegmentAlignment (&gSmmCorePrivate->PiSmmCoreImageContext); // // if Loading module at Fixed Address feature is enabled, the SMM core driver will be loaded to // the address assigned by build tool. @@ -1043,7 +1040,11 @@ ExecuteSmmCoreFromSmram ( // Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR // specified by SmramRange // - PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DestinationSize); + AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND ( + SmramRange->CpuStart + SmramRange->PhysicalSize, + DestinationAlignment + ); + PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DestinationSize) + (UINTN)EFI_SIZE_TO_PAGES ((UINTN)AlignSubtrahend); ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0); ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); @@ -1064,7 +1065,11 @@ ExecuteSmmCoreFromSmram ( // Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR // specified by SmramRange // - PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DestinationSize); + AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND ( + SmramRange->CpuStart + SmramRange->PhysicalSize, + DestinationAlignment + ); + PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DestinationSize) + (UINTN)EFI_SIZE_TO_PAGES ((UINTN)AlignSubtrahend); ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0); ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf index f7a19908d4..22a28df8e6 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf @@ -59,6 +59,7 @@ CpuExceptionHandlerLib DevicePathLib DxeServicesTableLib + MemoryAllocationLib [Guids] gEfiBootScriptExecutorVariableGuid ## PRODUCES ## UNDEFINED # SaveLockBox diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c index 70d06c9b6f..7371818a6e 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c @@ -12,8 +12,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "ScriptExecute.h" -#include "Library/UefiImageLib.h" -#include "Uefi/UefiBaseType.h" EFI_GUID mBootScriptExecutorImageGuid = { 0x9a8d3433, 0x9fe8, 0x42b6, { 0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b } @@ -275,8 +273,9 @@ ReadyToLockEventNotify ( UINTN BufferSize; EFI_HANDLE NewImageHandle; UINTN Pages; - EFI_PHYSICAL_ADDRESS FfsBuffer; - UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 ImageSize; + UINT32 ImageAlignment; EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; EFI_PHYSICAL_ADDRESS LoadAddress; @@ -313,40 +312,37 @@ ReadyToLockEventNotify ( // Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize); ASSERT_EFI_ERROR (Status); - UINT32 Size; - Status = UefiImageLoaderGetDestinationSize (&ImageContext, &Size); - ASSERT_EFI_ERROR (Status); - Pages = EFI_SIZE_TO_PAGES (Size); - FfsBuffer = 0xFFFFFFFF; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - Pages, - &FfsBuffer - ); + ImageSize = UefiImageGetImageSize (&ImageContext); + ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); + Pages = EFI_SIZE_TO_PAGES (ImageSize); + LoadAddress = 0xFFFFFFFF; + Status = AllocateAlignedPagesEx ( + AllocateMaxAddress, + EfiReservedMemoryType, + Pages, + ImageAlignment, + &LoadAddress + ); ASSERT_EFI_ERROR (Status); // // Make sure that the buffer can be used to store code. // - Status = gDS->GetMemorySpaceDescriptor (FfsBuffer, &MemDesc); + Status = gDS->GetMemorySpaceDescriptor (LoadAddress, &MemDesc); if (!EFI_ERROR (Status) && ((MemDesc.Attributes & EFI_MEMORY_XP) != 0)) { gDS->SetMemorySpaceAttributes ( - FfsBuffer, + LoadAddress, EFI_PAGES_TO_SIZE (Pages), MemDesc.Attributes & (~EFI_MEMORY_XP) ); } - LoadAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer; // // Load the image to our new buffer // - Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *)(UINTN)LoadAddress, Size, NULL, 0); + Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *)(UINTN)LoadAddress, ImageSize, NULL, 0); ASSERT_EFI_ERROR (Status); - LoadAddress = UefiImageLoaderGetImageAddress (&ImageContext); - // // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer // diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h index 8b80d1fbee..c18e6ed551 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h @@ -34,6 +34,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h index 0a83a9cc45..0595334718 100644 --- a/MdePkg/Include/Library/UefiImageLib.h +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -139,26 +139,6 @@ UefiImageHashImageDefault ( IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate ); -/** - Calculate the size, in Bytes, required for the destination Image memory space - to load into with UefiImageLoadImage(). This potentially includes additional - space to internally align the Image within the destination buffer. - - @param[in,out] Context The context describing the Image. Must have been - initialised by UefiImageInitializeContext(). - @param[out] Size On output, the size, in Bytes, required to allocate - the Image destination buffer. - - @retval RETURN_SUCCESS The Image destination size has been calculated - successfully. - @retval other The Image destination cannot be calculated. -**/ -RETURN_STATUS -UefiImageLoaderGetDestinationSize ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - OUT UINT32 *Size - ); - /** Load the Image into the destination memory space. @@ -168,7 +148,7 @@ UefiImageLoaderGetDestinationSize ( from page memory. @param[in] DestinationSize The size, in Bytes, of Destination. Must be at least as large as the size returned by - UefiImageLoaderGetDestinationSize(). + UefiImageGetImageSize(). @retval RETURN_SUCCESS The Image was loaded successfully. @retval other The Image could not be loaded successfully. @@ -275,7 +255,7 @@ UefiImageRelocateImage ( allocated from page memory. @param[in] DestinationSize The size, in Bytes, of Destination. Must be at least as large as the size returned by - UefiImageLoaderGetDestinationSize(). + UefiImageGetImageSize(). @param[out] RuntimeContext If not NULL, on output, a buffer bookkeeping data required for Image runtime relocation. diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c b/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c index 4d89960e5c..0a33419440 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c @@ -12,7 +12,6 @@ **/ #include -#include #include @@ -107,42 +106,15 @@ PeCoffLoadImage ( IN UINT32 DestinationSize ) { - UINT32 AlignOffset; - UINT32 AlignedSize; UINT32 LoadedHeaderSize; CONST EFI_IMAGE_SECTION_HEADER *Sections; - UINTN DestAddress; ASSERT (Context != NULL); ASSERT (Destination != NULL); - ASSERT (Context->SectionAlignment <= DestinationSize); - // - // Sufficiently align the Image data in memory. - // - if (Context->SectionAlignment <= EFI_PAGE_SIZE) { - // - // The caller is required to allocate page memory, hence we have at least - // 4 KB alignment guaranteed. - // - AlignOffset = 0; - AlignedSize = DestinationSize; - Context->ImageBuffer = Destination; - } else { - // - // Images aligned stricter than by the UEFI page size have an increased - // destination size to internally align the Image. - // - DestAddress = (UINTN) Destination; - AlignOffset = ALIGN_VALUE_ADDEND ((UINT32) DestAddress, Context->SectionAlignment); - AlignedSize = DestinationSize - AlignOffset; - Context->ImageBuffer = (CHAR8 *) Destination + AlignOffset; + ASSERT (ADDRESS_IS_ALIGNED (Destination, Context->SectionAlignment)); + ASSERT (Context->SizeOfImage <= DestinationSize); - ASSERT (Context->SizeOfImage <= AlignedSize); - - ZeroMem (Destination, AlignOffset); - } - - ASSERT (AlignedSize >= Context->SizeOfImage); + Context->ImageBuffer = Destination; // // Load the Image Headers into the memory space, if the policy demands it. // @@ -158,7 +130,7 @@ PeCoffLoadImage ( // // Load all Image sections into the memory space. // - InternalLoadSections (Context, LoadedHeaderSize, AlignedSize); + InternalLoadSections (Context, LoadedHeaderSize, DestinationSize); return RETURN_SUCCESS; } diff --git a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c index 8c9f713d65..7ae34b4c8d 100644 --- a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c @@ -32,42 +32,6 @@ UefiImageInitializeContext ( return UefiImageInitializeContextPostHash (Context); } -RETURN_STATUS -UefiImageLoaderGetDestinationSize ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - OUT UINT32 *Size - ) -{ - BOOLEAN Overflow; - UINT32 AlignedSize; - UINT32 SegmentAlignment; - - ASSERT (Context != NULL); - ASSERT (Size != NULL); - - AlignedSize = UefiImageGetImageSize (Context); - SegmentAlignment = UefiImageGetSegmentAlignment (Context); - // - // If the Image segment alignment is larger than the UEFI page size, - // sufficient alignment cannot be guaranteed by the allocater. Allodate an - // additional Image page to be able to manually align within the buffer. - // - if (SegmentAlignment > EFI_PAGE_SIZE) { - Overflow = BaseOverflowAddU32 ( - AlignedSize, - SegmentAlignment - EFI_PAGE_SIZE, - &AlignedSize - ); - if (Overflow) { - return RETURN_UNSUPPORTED; - } - } - - *Size = AlignedSize; - - return RETURN_SUCCESS; -} - UINTN UefiImageLoaderGetImageEntryPoint ( IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index 4f2b4d585f..663b847465 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -272,12 +272,11 @@ MmLoadImage ( IN OUT EFI_MM_DRIVER_ENTRY *DriverEntry ) { - UINT32 DestinationSize; - UINTN ImageSize; + UINT32 ImageSize; + UINT32 ImageAlignment; UINTN PageCount; EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS DstBuffer; - UINTN ImageBase; + VOID *DstBuffer; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; DEBUG ((DEBUG_INFO, "MmLoadImage - %g\n", &DriverEntry->FileName)); @@ -292,45 +291,30 @@ MmLoadImage ( return Status; } - Status = UefiImageLoaderGetDestinationSize (&ImageContext, &DestinationSize); - if (RETURN_ERROR (Status)) { - return Status; - } + ImageSize = UefiImageGetImageSize (&ImageContext, &ImageSize); + ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); - PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN) DestinationSize); - DstBuffer = (UINTN)(-1); + PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN) ImageSize); - Status = MmAllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesCode, - PageCount, - &DstBuffer - ); - if (EFI_ERROR (Status)) { - return Status; + DstBuffer = AllocateAlignedCodePages (PageCount, ImageAlignment); + if (DstBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; } // // Load the image to our new buffer // - Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *) (UINTN) DstBuffer, DestinationSize, NULL, 0); + Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *) (UINTN) DstBuffer, ImageSize, NULL, 0); if (EFI_ERROR (Status)) { - MmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, PageCount); return Status; } - ImageBase = UefiImageLoaderGetImageAddress (&ImageContext); - - // - // Flush the instruction cache so the image data are written before we execute it - // - ImageSize = UefiImageGetImageSize (&ImageContext); - // // Save Image EntryPoint in DriverEntry // - DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); - DriverEntry->ImageBuffer = DstBuffer; + DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); + DriverEntry->ImageBuffer = (UINTN)DstBuffer; DriverEntry->NumberOfPage = PageCount; if (mEfiSystemTable != NULL) { @@ -340,7 +324,7 @@ MmLoadImage ( (VOID **)&DriverEntry->LoadedImage ); if (EFI_ERROR (Status)) { - MmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, PageCount); return Status; } @@ -355,7 +339,7 @@ MmLoadImage ( DriverEntry->LoadedImage->DeviceHandle = NULL; DriverEntry->LoadedImage->FilePath = NULL; - DriverEntry->LoadedImage->ImageBase = (VOID *) ImageBase; + DriverEntry->LoadedImage->ImageBase = DstBuffer; DriverEntry->LoadedImage->ImageSize = ImageSize; DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode; DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData; diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index 302a828189..2d0df9a9c1 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -31,6 +31,7 @@ LoadUefiImage ( RETURN_STATUS Status; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT32 BufferSize; + UINT32 BufferAlignment; VOID *Buffer; Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize); @@ -39,16 +40,13 @@ LoadUefiImage ( return Status; } - Status = UefiImageLoaderGetDestinationSize (&ImageContext, &BufferSize); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } + BufferSize = UefiImageGetImageSize (&ImageContext); + BufferAlignment = UefiImageGetSegmentAlignment (&ImageContext); // // Allocate Memory for the image // - Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES (BufferSize)); + Buffer = AllocateAlignedCodePages (EFI_SIZE_TO_PAGES (BufferSize), BufferAlignment); if (Buffer == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -68,8 +66,8 @@ LoadUefiImage ( return Status; } - *ImageAddress = UefiImageLoaderGetImageAddress (&ImageContext); - *ImageSize = UefiImageGetImageSize (&ImageContext); + *ImageAddress = (UINTN)Buffer; + *ImageSize = BufferSize; *EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); return EFI_SUCCESS;