summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/Library
diff options
context:
space:
mode:
authorBrijesh Singh <brijesh.singh@amd.com>2021-12-09 11:27:44 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-12-09 06:28:10 +0000
commit11b15336f0ced4879529708f734a83adf69faf47 (patch)
tree9c13890394f9795324894b1944b33b4540ba719e /OvmfPkg/Library
parentd706f8fec256585de76280d2a1e1aa9550cefe12 (diff)
downloadedk2-11b15336f0ced4879529708f734a83adf69faf47.tar.gz
edk2-11b15336f0ced4879529708f734a83adf69faf47.tar.bz2
edk2-11b15336f0ced4879529708f734a83adf69faf47.zip
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>
Diffstat (limited to 'OvmfPkg/Library')
-rw-r--r--OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf2
-rw-r--r--OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c67
2 files changed, 68 insertions, 1 deletions
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
index 0402e49a10..49d5bd1bef 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
@@ -58,3 +58,5 @@
[FixedPcd]
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
index bc891c2636..2d2136f805 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
@@ -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;
+ }
}