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 <ardb+tianocore@kernel.org>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Michael Roth <michael.roth@amd.com>
Cc: Min Xu <min.m.xu@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Tom Lendacky 2024-03-08 07:32:10 -08:00 committed by mergify[bot]
parent ee89b59430
commit f6bf37c171
4 changed files with 9 additions and 74 deletions

View File

@ -1,7 +1,7 @@
## @file
# Library provides the helper functions for SEV guest
#
# Copyright (c) 2017 - 2020, Advanced Micro Devices. All rights reserved.<BR>
# Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@ -52,6 +52,7 @@
MemoryAllocationLib
PcdLib
CcExitLib
AmdSvsmLib
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire

View File

@ -1,7 +1,7 @@
## @file
# Library provides the helper functions for SEV guest
#
# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.<BR>
# Copyright (c) 2020 - 2024, Advanced Micro Devices. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@ -52,6 +52,7 @@
MemoryAllocationLib
PcdLib
CcExitLib
AmdSvsmLib
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire

View File

@ -1,7 +1,7 @@
## @file
# Library provides the helper functions for SEV guest
#
# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.<BR>
# Copyright (c) 2020 - 2024, Advanced Micro Devices. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@ -49,6 +49,7 @@
DebugLib
PcdLib
CcExitLib
AmdSvsmLib
[FixedPcd]
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase

View File

@ -14,14 +14,13 @@
#include <Library/MemEncryptSevLib.h>
#include <Library/DebugLib.h>
#include <Library/CcExitLib.h>
#include <Library/AmdSvsmLib.h>
#include <Register/Amd/Ghcb.h>
#include <Register/Amd/Msr.h>
#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);
}
}
}