summaryrefslogtreecommitdiff
path: root/OvmfPkg/Sec
diff options
context:
space:
mode:
Diffstat (limited to 'OvmfPkg/Sec')
-rw-r--r--OvmfPkg/Sec/AmdSev.c58
-rw-r--r--OvmfPkg/Sec/AmdSev.h14
-rw-r--r--OvmfPkg/Sec/SecMain.c1
-rw-r--r--OvmfPkg/Sec/SecMain.inf3
4 files changed, 76 insertions, 0 deletions
diff --git a/OvmfPkg/Sec/AmdSev.c b/OvmfPkg/Sec/AmdSev.c
index 520b125..89fba2f 100644
--- a/OvmfPkg/Sec/AmdSev.c
+++ b/OvmfPkg/Sec/AmdSev.c
@@ -8,7 +8,10 @@
**/
#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/CpuPageTableLib.h>
#include <Library/DebugLib.h>
+#include <Library/LocalApicLib.h>
#include <Library/MemEncryptSevLib.h>
#include <Library/BaseMemoryLib.h>
#include <Register/Amd/Ghcb.h>
@@ -301,3 +304,58 @@ SecValidateSystemRam (
MemEncryptSevSnpPreValidateSystemRam (Start, EFI_SIZE_TO_PAGES ((UINTN)(End - Start)));
}
}
+
+/**
+ Map known MMIO regions unencrypted if SEV-ES is active.
+
+ During early booting, page table entries default to having the encryption bit
+ set for SEV-ES/SEV-SNP guests. In cases where there is MMIO to an address, the
+ encryption bit should be cleared. Clear it here for any known MMIO accesses
+ during SEC, which is currently just the APIC base address.
+
+**/
+VOID
+SecMapApicBaseUnencrypted (
+ VOID
+ )
+{
+ PHYSICAL_ADDRESS Cr3;
+ UINT64 ApicAddress;
+ VOID *Buffer;
+ UINTN BufferSize;
+ IA32_MAP_ATTRIBUTE MapAttribute;
+ IA32_MAP_ATTRIBUTE MapMask;
+ RETURN_STATUS Status;
+
+ if (!SevEsIsEnabled ()) {
+ return;
+ }
+
+ ApicAddress = (UINT64)GetLocalApicBaseAddress ();
+ Buffer = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecApicPageTableBase);
+ Cr3 = AsmReadCr3 ();
+
+ MapAttribute.Uint64 = ApicAddress;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
+ MapMask.Uint64 = MAX_UINT64;
+ BufferSize = SIZE_4KB;
+
+ Status = PageTableMap (
+ (UINTN *)&Cr3,
+ Paging4Level,
+ Buffer,
+ &BufferSize,
+ ApicAddress,
+ SIZE_4KB,
+ &MapAttribute,
+ &MapMask,
+ NULL
+ );
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to map APIC MMIO region as unencrypted: %d\n", Status));
+ ASSERT (FALSE);
+ }
+
+ CpuFlushTlb ();
+}
diff --git a/OvmfPkg/Sec/AmdSev.h b/OvmfPkg/Sec/AmdSev.h
index f758770..c5ab0d5 100644
--- a/OvmfPkg/Sec/AmdSev.h
+++ b/OvmfPkg/Sec/AmdSev.h
@@ -91,4 +91,18 @@ SevSnpIsEnabled (
VOID
);
+/**
+ Map MMIO regions unencrypted if SEV-ES is active.
+
+ During early booting, page table entries default to having the encryption bit
+ set for SEV-ES/SEV-SNP guests. In cases where there is MMIO to an address, the
+ encryption bit should be cleared. Clear it here for any known MMIO accesses
+ during SEC, which is currently just the APIC base address.
+
+**/
+VOID
+SecMapApicBaseUnencrypted (
+ VOID
+ );
+
#endif
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index a30d4ce..60dfa61 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -938,6 +938,7 @@ SecCoreStartupWithStack (
// interrupts before initializing the Debug Agent and the debug timer is
// enabled.
//
+ SecMapApicBaseUnencrypted ();
InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
DisableApicTimerInterrupt ();
diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf
index dca932a..88c2d3f 100644
--- a/OvmfPkg/Sec/SecMain.inf
+++ b/OvmfPkg/Sec/SecMain.inf
@@ -55,6 +55,7 @@
MemEncryptSevLib
CpuExceptionHandlerLib
CcProbeLib
+ CpuPageTableLib
[Ppis]
gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
@@ -83,6 +84,8 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableSize
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire