From: Tom Lendacky <thomas.lenda...@amd.com>

The SEV support will clear the C-bit from non-RAM areas.  The early GDT
lives in a non-RAM area, so when an exception occurs (like a #VC) the GDT
will be read as un-encrypted even though it is encrypted. This will result
in a failure to be able to handle the exception.

Move the GDT into RAM so it can be accessed without error when running as
an SEV-ES guest.

Signed-off-by: Tom Lendacky <thomas.lenda...@amd.com>
---
 OvmfPkg/PlatformPei/AmdSev.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 87ac842a1590..5f4983fd36d8 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -37,6 +37,8 @@ AmdSevEsInitialize (
   PHYSICAL_ADDRESS  GhcbBasePa;
   UINTN             GhcbPageCount;
   RETURN_STATUS     DecryptStatus, PcdStatus;
+  IA32_DESCRIPTOR   Gdtr;
+  VOID              *Gdt;
 
   if (!MemEncryptSevEsIsEnabled ()) {
     return;
@@ -76,6 +78,20 @@ AmdSevEsInitialize (
   DEBUG ((DEBUG_INFO, "SEV-ES is enabled, %u GHCB pages allocated starting at 
0x%lx\n", GhcbPageCount, GhcbBase));
 
   AsmWriteMsr64 (MSR_SEV_ES_GHCB, (UINT64)GhcbBasePa);
+
+  //
+  // The SEV support will clear the C-bit from the non-RAM areas. Since
+  // the GDT initially lives in that area and it will be read when a #VC
+  // exception happens, it needs to be moved to RAM for an SEV-ES guest.
+  //
+  AsmReadGdtr (&Gdtr);
+
+  Gdt = AllocatePool (Gdtr.Limit + 1);
+  ASSERT (Gdt);
+
+  CopyMem (Gdt, (VOID *) Gdtr.Base, Gdtr.Limit + 1);
+  Gdtr.Base = (UINTN) Gdt;
+  AsmWriteGdtr (&Gdtr);
 }
 
 /**
-- 
2.17.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#46111): https://edk2.groups.io/g/devel/message/46111
Mute This Topic: https://groups.io/mt/32966283/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to