summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/PlatformPei/AmdSev.c
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2021-01-07 12:48:23 -0600
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-01-07 19:34:39 +0000
commit5667dc43d82396589d2fabd790e7f6a214386969 (patch)
treeddf0d66ff4e0d7e5f9a456018fca515c358884e6 /OvmfPkg/PlatformPei/AmdSev.c
parentc330af0246ac9b1c37d17fc79881fc2dd96ec80c (diff)
downloadedk2-5667dc43d82396589d2fabd790e7f6a214386969.tar.gz
edk2-5667dc43d82396589d2fabd790e7f6a214386969.tar.bz2
edk2-5667dc43d82396589d2fabd790e7f6a214386969.zip
OvmfPkg/VmgExitLib: Support nested #VCs
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3108 In order to be able to issue messages or make interface calls that cause another #VC (e.g. GetLocalApicBaseAddress () issues RDMSR), add support for nested #VCs. In order to support nested #VCs, GHCB backup pages are required. If a #VC is received while currently processing a #VC, a backup of the current GHCB content is made. This allows the #VC handler to continue processing the new #VC. Upon completion of the new #VC, the GHCB is restored from the backup page. The #VC recursion level is tracked in the per-vCPU variable area. Support is added to handle up to one nested #VC (or two #VCs total). If a second nested #VC is encountered, an ASSERT will be issued and the vCPU will enter CpuDeadLoop (). For SEC, the GHCB backup pages are reserved in the OvmfPkgX64.fdf memory layout, with two new fixed PCDs to provide the address and size of the backup area. For PEI/DXE, the GHCB backup pages are allocated as boot services pages using the memory allocation library. Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Acked-by: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Message-Id: <ac2e8203fc41a351b43f60d68bdad6b57c4fb106.1610045305.git.thomas.lendacky@amd.com>
Diffstat (limited to 'OvmfPkg/PlatformPei/AmdSev.c')
-rw-r--r--OvmfPkg/PlatformPei/AmdSev.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 954d53eba4..dddffdebda 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -33,12 +33,17 @@ AmdSevEsInitialize (
VOID
)
{
- VOID *GhcbBase;
- PHYSICAL_ADDRESS GhcbBasePa;
- UINTN GhcbPageCount, PageCount;
- RETURN_STATUS PcdStatus, DecryptStatus;
- IA32_DESCRIPTOR Gdtr;
- VOID *Gdt;
+ UINT8 *GhcbBase;
+ PHYSICAL_ADDRESS GhcbBasePa;
+ UINTN GhcbPageCount;
+ UINT8 *GhcbBackupBase;
+ UINT8 *GhcbBackupPages;
+ UINTN GhcbBackupPageCount;
+ SEV_ES_PER_CPU_DATA *SevEsData;
+ UINTN PageCount;
+ RETURN_STATUS PcdStatus, DecryptStatus;
+ IA32_DESCRIPTOR Gdtr;
+ VOID *Gdt;
if (!MemEncryptSevEsIsEnabled ()) {
return;
@@ -84,6 +89,27 @@ AmdSevEsInitialize (
"SEV-ES is enabled, %lu GHCB pages allocated starting at 0x%p\n",
(UINT64)GhcbPageCount, GhcbBase));
+ //
+ // Allocate #VC recursion backup pages. The number of backup pages needed is
+ // one less than the maximum VC count.
+ //
+ GhcbBackupPageCount = mMaxCpuCount * (VMGEXIT_MAXIMUM_VC_COUNT - 1);
+ GhcbBackupBase = AllocatePages (GhcbBackupPageCount);
+ ASSERT (GhcbBackupBase != NULL);
+
+ GhcbBackupPages = GhcbBackupBase;
+ for (PageCount = 1; PageCount < GhcbPageCount; PageCount += 2) {
+ SevEsData =
+ (SEV_ES_PER_CPU_DATA *)(GhcbBase + EFI_PAGES_TO_SIZE (PageCount));
+ SevEsData->GhcbBackupPages = GhcbBackupPages;
+
+ GhcbBackupPages += EFI_PAGE_SIZE * (VMGEXIT_MAXIMUM_VC_COUNT - 1);
+ }
+
+ DEBUG ((DEBUG_INFO,
+ "SEV-ES is enabled, %lu GHCB backup pages allocated starting at 0x%p\n",
+ (UINT64)GhcbBackupPageCount, GhcbBackupBase));
+
AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa);
//