From 61a044c6c15f5806a30ff23409ba5287d9d07163 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 1 Mar 2018 17:31:44 +0100 Subject: [PATCH] OvmfPkg/MemEncryptSevLib: find pages of initial SMRAM save state map In the next three patches, we're going to modify three modules under OvmfPkg. When OVMF is built with -D SMM_REQUIRE and runs in an SEV guest, each affected module will have to know the page range that covers the initial (pre-SMBASE relocation) SMRAM save state map. Add a helper function to MemEncryptSevLib that calculates the "base address" and "number of pages" constants for this page range. (In a RELEASE build -- i.e., with assertions disabled and optimization enabled --, the helper function can be compiled to store two constants determined at compile time.) Cc: Ard Biesheuvel Cc: Brijesh Singh Cc: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek Tested-by: Brijesh Singh Reviewed-by: Brijesh Singh --- OvmfPkg/Include/Library/MemEncryptSevLib.h | 23 +++++++++ .../BaseMemEncryptSevLib.inf | 4 ++ .../MemEncryptSevLibInternal.c | 51 +++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h index e5ebb44018..1e2ec8641d 100644 --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h @@ -86,4 +86,27 @@ MemEncryptSevSetPageEncMask ( IN UINTN NumPages, IN BOOLEAN Flush ); + + +/** + Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM + Save State Map. + + @param[out] BaseAddress The base address of the lowest-address page that + covers the initial SMRAM Save State Map. + + @param[out] NumberOfPages The number of pages in the page range that covers + the initial SMRAM Save State Map. + + @retval RETURN_SUCCESS BaseAddress and NumberOfPages have been set on + output. + + @retval RETURN_UNSUPPORTED SMM is unavailable. +**/ +RETURN_STATUS +EFIAPI +MemEncryptSevLocateInitialSmramSaveStateMapPages ( + OUT UINTN *BaseAddress, + OUT UINTN *NumberOfPages + ); #endif // _MEM_ENCRYPT_SEV_LIB_H_ diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf index 2f0a2392a7..464fe1f33e 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf @@ -51,3 +51,7 @@ CpuLib DebugLib MemoryAllocationLib + PcdLib + +[FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c index 7078ab0d3f..b92ba50c61 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c @@ -17,9 +17,13 @@ #include #include #include +#include #include #include #include +#include +#include +#include STATIC BOOLEAN mSevStatus = FALSE; STATIC BOOLEAN mSevStatusChecked = FALSE; @@ -87,3 +91,50 @@ MemEncryptSevIsEnabled ( return mSevStatus; } + + +/** + Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM + Save State Map. + + @param[out] BaseAddress The base address of the lowest-address page that + covers the initial SMRAM Save State Map. + + @param[out] NumberOfPages The number of pages in the page range that covers + the initial SMRAM Save State Map. + + @retval RETURN_SUCCESS BaseAddress and NumberOfPages have been set on + output. + + @retval RETURN_UNSUPPORTED SMM is unavailable. +**/ +RETURN_STATUS +EFIAPI +MemEncryptSevLocateInitialSmramSaveStateMapPages ( + OUT UINTN *BaseAddress, + OUT UINTN *NumberOfPages + ) +{ + UINTN MapStart; + UINTN MapEnd; + UINTN MapPagesStart; // MapStart rounded down to page boundary + UINTN MapPagesEnd; // MapEnd rounded up to page boundary + UINTN MapPagesSize; // difference between MapPagesStart and MapPagesEnd + + if (!FeaturePcdGet (PcdSmmSmramRequire)) { + return RETURN_UNSUPPORTED; + } + + MapStart = SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET; + MapEnd = MapStart + sizeof (QEMU_SMRAM_SAVE_STATE_MAP); + MapPagesStart = MapStart & ~(UINTN)EFI_PAGE_MASK; + MapPagesEnd = ALIGN_VALUE (MapEnd, EFI_PAGE_SIZE); + MapPagesSize = MapPagesEnd - MapPagesStart; + + ASSERT ((MapPagesSize & EFI_PAGE_MASK) == 0); + + *BaseAddress = MapPagesStart; + *NumberOfPages = MapPagesSize >> EFI_PAGE_SHIFT; + + return RETURN_SUCCESS; +} -- 2.39.2