From f6bf37c1711c07709b0817a996c5b5a97f263bdd Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Fri, 8 Mar 2024 07:32:10 -0800 Subject: [PATCH] OvmfPkg/BaseMemEncryptSevLib: Use AmdSvsmSnpPvalidate() to validate pages BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654 The PVALIDATE instruction is used to change the SNP validation of a page, but that can only be done when running at VMPL0. To prepare for running at a less priviledged VMPL, use the AmdSvsmLib library API to perform the PVALIDATE. The AmdSvsmLib library will perform the proper operation on behalf of the caller. Cc: Ard Biesheuvel Cc: Erdem Aktas Cc: Gerd Hoffmann Cc: Jiewen Yao Cc: Laszlo Ersek Cc: Michael Roth Cc: Min Xu Signed-off-by: Tom Lendacky Acked-by: Gerd Hoffmann --- .../DxeMemEncryptSevLib.inf | 3 +- .../PeiMemEncryptSevLib.inf | 3 +- .../SecMemEncryptSevLib.inf | 3 +- .../X64/SnpPageStateChangeInternal.c | 74 +------------------ 4 files changed, 9 insertions(+), 74 deletions(-) diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf index cc24961c92..312ee73e54 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf @@ -1,7 +1,7 @@ ## @file # Library provides the helper functions for SEV guest # -# Copyright (c) 2017 - 2020, Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -52,6 +52,7 @@ MemoryAllocationLib PcdLib CcExitLib + AmdSvsmLib [FeaturePcd] gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf index 8f56783da5..1e0b5600eb 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf @@ -1,7 +1,7 @@ ## @file # Library provides the helper functions for SEV guest # -# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2020 - 2024, Advanced Micro Devices. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -52,6 +52,7 @@ MemoryAllocationLib PcdLib CcExitLib + AmdSvsmLib [FeaturePcd] gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf index b6d76e7e63..a06ea6188e 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf @@ -1,7 +1,7 @@ ## @file # Library provides the helper functions for SEV guest # -# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2020 - 2024, Advanced Micro Devices. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -49,6 +49,7 @@ DebugLib PcdLib CcExitLib + AmdSvsmLib [FixedPcd] gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c index f1883239a6..c8c0c4ef0e 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c @@ -14,14 +14,13 @@ #include #include #include +#include #include #include #include "SnpPageStateChange.h" -#define PAGES_PER_LARGE_ENTRY 512 - STATIC UINTN MemoryStateToGhcbOp ( @@ -63,73 +62,6 @@ SnpPageStateFailureTerminate ( CpuDeadLoop (); } -/** - This function issues the PVALIDATE instruction to validate or invalidate the memory - range specified. If PVALIDATE returns size mismatch then it retry validating with - smaller page size. - - */ -STATIC -VOID -PvalidateRange ( - IN SNP_PAGE_STATE_CHANGE_INFO *Info - ) -{ - UINTN RmpPageSize; - UINTN StartIndex; - UINTN EndIndex; - UINTN Index; - UINTN Ret; - EFI_PHYSICAL_ADDRESS Address; - BOOLEAN Validate; - - StartIndex = Info->Header.CurrentEntry; - EndIndex = Info->Header.EndEntry; - - for ( ; StartIndex <= EndIndex; StartIndex++) { - // - // Get the address and the page size from the Info. - // - Address = ((EFI_PHYSICAL_ADDRESS)Info->Entry[StartIndex].GuestFrameNumber) << EFI_PAGE_SHIFT; - RmpPageSize = Info->Entry[StartIndex].PageSize; - Validate = Info->Entry[StartIndex].Operation == SNP_PAGE_STATE_PRIVATE; - - Ret = AsmPvalidate (RmpPageSize, Validate, Address); - - // - // If we fail to validate due to size mismatch then try with the - // smaller page size. This senario will occur if the backing page in - // the RMP entry is 4K and we are validating it as a 2MB. - // - if ((Ret == PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize == PvalidatePageSize2MB)) { - for (Index = 0; Index < PAGES_PER_LARGE_ENTRY; Index++) { - Ret = AsmPvalidate (PvalidatePageSize4K, Validate, Address); - if (Ret) { - break; - } - - Address = Address + EFI_PAGE_SIZE; - } - } - - // - // If validation failed then do not continue. - // - if (Ret) { - DEBUG (( - DEBUG_ERROR, - "%a:%a: Failed to %a address 0x%Lx Error code %d\n", - gEfiCallerBaseName, - __func__, - Validate ? "Validate" : "Invalidate", - Address, - Ret - )); - SnpPageStateFailureTerminate (); - } - } -} - STATIC EFI_PHYSICAL_ADDRESS BuildPageStateBuffer ( @@ -328,7 +260,7 @@ InternalSetPageState ( // invalidate the pages before making the page shared in the RMP table. // if (State == SevSnpPageShared) { - PvalidateRange (Info); + AmdSvsmSnpPvalidate (Info); } // @@ -341,7 +273,7 @@ InternalSetPageState ( // validate the pages after it has been added in the RMP table. // if (State == SevSnpPagePrivate) { - PvalidateRange (Info); + AmdSvsmSnpPvalidate (Info); } } }