summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikolaj Lisik via groups.io <lisik=google.com@groups.io>2023-01-26 20:26:40 +0000
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-06-02 23:59:20 +0000
commitc1dd400a13d1a5e862809c55f6760ba3a944a609 (patch)
treedeedeb5875cb86250f1f1af000319173a104275a
parent8fbf857a0b42697c22ec03abda9a2101b2870812 (diff)
downloadedk2-c1dd400a13d1a5e862809c55f6760ba3a944a609.tar.gz
edk2-c1dd400a13d1a5e862809c55f6760ba3a944a609.tar.bz2
edk2-c1dd400a13d1a5e862809c55f6760ba3a944a609.zip
OvmfPkg: Create additional PML1 entries for large SEV-SNP VMs
Edk2 was failing, rather than creating more PML4 entries, when they weren't present in the initial memory acceptance flow. Because of that VMs with more than 512G memory were crashing. This code fixes that. This change affects only SEV-SNP VMs. The code was tested by successfully booting a 512G SEV-SNP VM. Signed-off-by: Mikolaj Lisik <lisik@google.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
-rw-r--r--OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index a1f6e61c1e..cf2441b551 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -548,6 +548,7 @@ InternalMemEncryptSevCreateIdentityMap1G (
PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
UINT64 PgTableMask;
+ UINT64 *NewPageTable;
UINT64 AddressEncMask;
BOOLEAN IsWpEnabled;
RETURN_STATUS Status;
@@ -602,15 +603,23 @@ InternalMemEncryptSevCreateIdentityMap1G (
PageMapLevel4Entry = (VOID *)(Cr3BaseAddress & ~PgTableMask);
PageMapLevel4Entry += PML4_OFFSET (PhysicalAddress);
if (!PageMapLevel4Entry->Bits.Present) {
- DEBUG ((
- DEBUG_ERROR,
- "%a:%a: bad PML4 for Physical=0x%Lx\n",
- gEfiCallerBaseName,
- __func__,
- PhysicalAddress
- ));
- Status = RETURN_NO_MAPPING;
- goto Done;
+ NewPageTable = AllocatePageTableMemory (1);
+ if (NewPageTable == NULL) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a:%a: failed to allocate a new PML4 entry\n",
+ gEfiCallerBaseName,
+ __func__
+ ));
+ Status = RETURN_NO_MAPPING;
+ goto Done;
+ }
+
+ SetMem (NewPageTable, EFI_PAGE_SIZE, 0);
+ PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)NewPageTable | AddressEncMask;
+ PageMapLevel4Entry->Bits.MustBeZero = 0;
+ PageMapLevel4Entry->Bits.ReadWrite = 1;
+ PageMapLevel4Entry->Bits.Present = 1;
}
PageDirectory1GEntry = (VOID *)(