OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The MemEncryptSevSnpPreValidateSystemRam() is used for pre-validating the
system RAM. As the boot progress, each phase validates a fixed region of
the RAM. In the PEI phase, the PlatformPei detects all the available RAM
and calls to pre-validate the detected system RAM.

While validating the system RAM in PEI phase, we must skip previously
validated system RAM to avoid the double validation.

Cc: Michael Roth <michael.roth@amd.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
This commit is contained in:
Brijesh Singh 2021-12-09 11:27:44 +08:00 committed by mergify[bot]
parent d706f8fec2
commit 11b15336f0
2 changed files with 68 additions and 1 deletions

View File

@ -58,3 +58,5 @@
[FixedPcd]
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase

View File

@ -14,6 +14,46 @@
#include "SnpPageStateChange.h"
typedef struct {
UINT64 StartAddress;
UINT64 EndAddress;
} SNP_PRE_VALIDATED_RANGE;
STATIC SNP_PRE_VALIDATED_RANGE mPreValidatedRange[] = {
// The below address range was part of the SEV OVMF metadata, and range
// should be pre-validated by the Hypervisor.
{
FixedPcdGet32 (PcdOvmfSecPageTablesBase),
FixedPcdGet32 (PcdOvmfPeiMemFvBase),
},
};
STATIC
BOOLEAN
DetectPreValidatedOverLap (
IN PHYSICAL_ADDRESS StartAddress,
IN PHYSICAL_ADDRESS EndAddress,
OUT SNP_PRE_VALIDATED_RANGE *OverlapRange
)
{
UINTN i;
//
// Check if the specified address range exist in pre-validated array.
//
for (i = 0; i < ARRAY_SIZE (mPreValidatedRange); i++) {
if ((mPreValidatedRange[i].StartAddress < EndAddress) &&
(StartAddress < mPreValidatedRange[i].EndAddress))
{
OverlapRange->StartAddress = mPreValidatedRange[i].StartAddress;
OverlapRange->EndAddress = mPreValidatedRange[i].EndAddress;
return TRUE;
}
}
return FALSE;
}
/**
Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
@ -28,9 +68,34 @@ MemEncryptSevSnpPreValidateSystemRam (
IN UINTN NumPages
)
{
PHYSICAL_ADDRESS EndAddress;
SNP_PRE_VALIDATED_RANGE OverlapRange;
if (!MemEncryptSevSnpIsEnabled ()) {
return;
}
InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
EndAddress = BaseAddress + EFI_PAGES_TO_SIZE (NumPages);
while (BaseAddress < EndAddress) {
//
// Check if the range overlaps with the pre-validated ranges.
//
if (DetectPreValidatedOverLap (BaseAddress, EndAddress, &OverlapRange)) {
// Validate the non-overlap regions.
if (BaseAddress < OverlapRange.StartAddress) {
NumPages = EFI_SIZE_TO_PAGES (OverlapRange.StartAddress - BaseAddress);
InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
}
BaseAddress = OverlapRange.EndAddress;
continue;
}
// Validate the remaining pages.
NumPages = EFI_SIZE_TO_PAGES (EndAddress - BaseAddress);
InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
BaseAddress = EndAddress;
}
}