Background: In the PiSmmCpuDxeSmm driver, SMRAM allocation for SMI handlers and processor Save State areas was traditionally performed using the Smst->AllocatePages() function during the DXE phase. The introduction of SmmRelocationLib changes this process by moving the allocation to the PEI phase, where Smst->AllocatePages() is not accessible. Instead, the allocation is now handled by partitioning the SMRAM based on the information provided by a GUID HOB (identified by gEfiSmmSMramMemoryGuid).
This patch is to ensure that OVMF produces the gEfiSmmSMramMemoryGuid HOB, allowing SmmRelocationLib to reserve the necessary memory for SMBASE relocation. Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> Cc: Jiewen Yao <jiewen....@intel.com> Cc: Gerd Hoffmann <kra...@redhat.com> Cc: Ray Ni <ray...@intel.com> Signed-off-by: Jiaxin Wu <jiaxin...@intel.com> --- OvmfPkg/Library/PlatformInitLib/MemDetect.c | 97 +++++++++++++--------- .../Library/PlatformInitLib/PlatformInitLib.inf | 5 +- 2 files changed, 64 insertions(+), 38 deletions(-) diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c index 7b6e5102ad..8b98256225 100644 --- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c @@ -1,9 +1,9 @@ /**@file Memory Detection for Virtual Machines. - Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent Module Name: MemDetect.c @@ -41,10 +41,12 @@ Module Name: #include <Library/QemuFwCfgSimpleParserLib.h> #include <Library/TdxLib.h> #include <Library/PlatformInitLib.h> +#include <Guid/SmramMemoryReserve.h> + #define MEGABYTE_SHIFT 20 VOID EFIAPI PlatformQemuUc32BaseInitialization ( @@ -1027,52 +1029,73 @@ PlatformQemuInitializeRam ( // // Determine total memory size available // PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob); - if (PlatformInfoHob->BootMode == BOOT_ON_S3_RESUME) { - // - // Create the following memory HOB as an exception on the S3 boot path. + // + // CpuMpPei saves the original contents of the borrowed area in permanent + // PEI RAM, in a backup buffer allocated with the normal PEI services. + // CpuMpPei restores the original contents ("returns" the borrowed area) at + // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before + // transferring control to the OS's wakeup vector in the FACS. + // + // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to + // restore the original contents. Furthermore, we expect all such PEIMs + // (CpuMpPei included) to claim the borrowed areas by producing memory + // allocation HOBs, and to honor preexistent memory allocation HOBs when + // looking for an area to borrow. + // + QemuInitializeRamBelow1gb (PlatformInfoHob); + + if (PlatformInfoHob->SmmSmramRequire) { + UINT32 TsegSize; + UINTN BufferSize; + UINT8 SmramRanges; + EFI_PEI_HOB_POINTERS Hob; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock; + + TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB; + PlatformAddMemoryRangeHob (BASE_1MB, PlatformInfoHob->LowMemory - TsegSize); + PlatformAddReservedMemoryBaseSizeHob ( + PlatformInfoHob->LowMemory - TsegSize, + TsegSize, + TRUE + ); + + SmramRanges = 2; + BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + (SmramRanges - 1) * sizeof (EFI_SMRAM_DESCRIPTOR); + + Hob.Raw = BuildGuidHob ( + &gEfiSmmSmramMemoryGuid, + BufferSize + ); + ASSERT (Hob.Raw); + + SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)(Hob.Raw); + SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges; + // - // Normally we'd create memory HOBs only on the normal boot path. However, - // CpuMpPei specifically needs such a low-memory HOB on the S3 path as - // well, for "borrowing" a subset of it temporarily, for the AP startup - // vector. + // Create first SMRAM descriptor, which contains data structures used in S3 resume. + // One page is enough for the data structure // - // CpuMpPei saves the original contents of the borrowed area in permanent - // PEI RAM, in a backup buffer allocated with the normal PEI services. - // CpuMpPei restores the original contents ("returns" the borrowed area) at - // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before - // transferring control to the OS's wakeup vector in the FACS. + SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = PlatformInfoHob->LowMemory - TsegSize; + SmramHobDescriptorBlock->Descriptor[0].CpuStart = PlatformInfoHob->LowMemory - TsegSize; + SmramHobDescriptorBlock->Descriptor[0].PhysicalSize = EFI_PAGE_SIZE; + SmramHobDescriptorBlock->Descriptor[0].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE | EFI_ALLOCATED; + // - // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to - // restore the original contents. Furthermore, we expect all such PEIMs - // (CpuMpPei included) to claim the borrowed areas by producing memory - // allocation HOBs, and to honor preexistent memory allocation HOBs when - // looking for an area to borrow. + // Create second SMRAM descriptor, which is free and will be used by SMM foundation. // - QemuInitializeRamBelow1gb (PlatformInfoHob); + SmramHobDescriptorBlock->Descriptor[1].PhysicalStart = SmramHobDescriptorBlock->Descriptor[0].PhysicalStart + EFI_PAGE_SIZE; + SmramHobDescriptorBlock->Descriptor[1].CpuStart = SmramHobDescriptorBlock->Descriptor[0].CpuStart + EFI_PAGE_SIZE; + SmramHobDescriptorBlock->Descriptor[1].PhysicalSize = TsegSize - EFI_PAGE_SIZE; + SmramHobDescriptorBlock->Descriptor[1].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE; } else { - // - // Create memory HOBs - // - QemuInitializeRamBelow1gb (PlatformInfoHob); - - if (PlatformInfoHob->SmmSmramRequire) { - UINT32 TsegSize; - - TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB; - PlatformAddMemoryRangeHob (BASE_1MB, PlatformInfoHob->LowMemory - TsegSize); - PlatformAddReservedMemoryBaseSizeHob ( - PlatformInfoHob->LowMemory - TsegSize, - TsegSize, - TRUE - ); - } else { - PlatformAddMemoryRangeHob (BASE_1MB, PlatformInfoHob->LowMemory); - } + PlatformAddMemoryRangeHob (BASE_1MB, PlatformInfoHob->LowMemory); + } + if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) { // // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM // entries. Otherwise, create a single memory HOB with the flat >=4GB // memory size read from the CMOS. // diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf index 5a79d95b68..2bb1c0296f 100644 --- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf +++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf @@ -1,10 +1,10 @@ ## @file # Platform Initialization Lib # # This module provides platform specific function to detect boot mode. -# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -54,10 +54,13 @@ PeiHardwareInfoLib [LibraryClasses.X64] TdxLib +[Guids] + gEfiSmmSmramMemoryGuid + [Pcd] gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable [FixedPcd] -- 2.16.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117953): https://edk2.groups.io/g/devel/message/117953 Mute This Topic: https://groups.io/mt/105593577/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-