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.r...@amd.com> Cc: James Bottomley <j...@linux.ibm.com> Cc: Min Xu <min.m...@intel.com> Cc: Jiewen Yao <jiewen....@intel.com> Cc: Tom Lendacky <thomas.lenda...@amd.com> Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> Cc: Erdem Aktas <erdemak...@google.com> Cc: Gerd Hoffmann <kra...@redhat.com> Acked-by: Jiewen Yao <jiewen....@intel.com> Signed-off-by: Brijesh Singh <brijesh.si...@amd.com> --- .../PeiMemEncryptSevLib.inf | 20 ++++ .../X64/PeiSnpSystemRamValidate.c | 102 +++++++++++++++++- 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf index 0402e49a1028..1cc9dd6691a2 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf @@ -57,4 +57,24 @@ [FeaturePcd] gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire [FixedPcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress + gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c index 64aab7f45b6d..eae7a31773a4 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c @@ -14,6 +14,81 @@ #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 OVMF metadata, and range + // should be pre-validated by the Hypervisor. + { + FixedPcdGet32 (PcdOvmfSecPageTablesBase), + FixedPcdGet32 (PcdOvmfSecPageTablesBase) + FixedPcdGet32 (PcdOvmfSecPageTablesSize), + }, + { + FixedPcdGet32 (PcdOvmfLockBoxStorageBase), + FixedPcdGet32 (PcdOvmfLockBoxStorageBase) + FixedPcdGet32 (PcdOvmfLockBoxStorageSize), + }, + { + FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress), + FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress) + FixedPcdGet32 (PcdGuidedExtractHandlerTableSize) + }, + { + FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase), + FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase) + FixedPcdGet32 (PcdOvmfSecGhcbPageTableSize), + }, + { + FixedPcdGet32 (PcdOvmfSecGhcbBase), + FixedPcdGet32 (PcdOvmfSecGhcbBase) + FixedPcdGet32 (PcdOvmfSecGhcbSize), + }, + { + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaBase) + FixedPcdGet32 (PcdOvmfWorkAreaSize), + }, + { + FixedPcdGet32 (PcdOvmfSecGhcbBackupBase), + FixedPcdGet32 (PcdOvmfSecGhcbBackupBase) + FixedPcdGet32 (PcdOvmfSecGhcbBackupSize), + }, + { + FixedPcdGet32 (PcdOvmfSnpSecretsBase), + FixedPcdGet32 (PcdOvmfSnpSecretsBase) + FixedPcdGet32 (PcdOvmfSnpSecretsSize), + }, + { + FixedPcdGet32 (PcdOvmfCpuidBase), + FixedPcdGet32 (PcdOvmfCpuidBase) + FixedPcdGet32 (PcdOvmfCpuidSize), + }, + { + FixedPcdGet32 (PcdOvmfSecPeiTempRamBase), + FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize), + }, +}; + +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 +103,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; + } } -- 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#80901): https://edk2.groups.io/g/devel/message/80901 Mute This Topic: https://groups.io/mt/85749034/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-