OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase

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

The initial page built during the SEC phase is used by the
MemEncryptSevSnpValidateSystemRam() for the system RAM validation. The
page validation process requires using the PVALIDATE instruction;  the
instruction accepts a virtual address of the memory region that needs
to be validated. If hardware encounters a page table walk failure (due
to page-not-present) then it raises #GP.

The initial page table built in SEC phase address up to 4GB. Add an
internal function to extend the page table to cover > 4GB. The function
builds 1GB entries in the page table for access > 4GB. This will provide
the support to call PVALIDATE instruction for the virtual address >
4GB in PEI phase.

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 via groups.io
2021-12-09 11:27:45 +08:00
committed by mergify[bot]
parent 11b15336f0
commit d39f8d88ec
3 changed files with 160 additions and 0 deletions

View File

@@ -10,9 +10,12 @@
#include <Uefi/UefiBaseType.h>
#include <Library/BaseLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <Library/MemEncryptSevLib.h>
#include "SnpPageStateChange.h"
#include "VirtualMemory.h"
typedef struct {
UINT64 StartAddress;
@@ -70,6 +73,7 @@ MemEncryptSevSnpPreValidateSystemRam (
{
PHYSICAL_ADDRESS EndAddress;
SNP_PRE_VALIDATED_RANGE OverlapRange;
EFI_STATUS Status;
if (!MemEncryptSevSnpIsEnabled ()) {
return;
@@ -77,6 +81,24 @@ MemEncryptSevSnpPreValidateSystemRam (
EndAddress = BaseAddress + EFI_PAGES_TO_SIZE (NumPages);
//
// The page table used in PEI can address up to 4GB memory. If we are asked to
// validate a range above the 4GB, then create an identity mapping so that the
// PVALIDATE instruction can execute correctly. If the page table entry is not
// present then PVALIDATE will #GP.
//
if (BaseAddress >= SIZE_4GB) {
Status = InternalMemEncryptSevCreateIdentityMap1G (
0,
BaseAddress,
EFI_PAGES_TO_SIZE (NumPages)
);
if (EFI_ERROR (Status)) {
ASSERT (FALSE);
CpuDeadLoop ();
}
}
while (BaseAddress < EndAddress) {
//
// Check if the range overlaps with the pre-validated ranges.