diff options
author | Tom Lendacky <thomas.lendacky@amd.com> | 2024-03-08 07:30:35 -0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2024-04-17 18:30:03 +0000 |
commit | 4bd3b5ab13799765125b5ff2d126bc1565eaedac (patch) | |
tree | e40c919d3ac9531747ce36b7f5c9c73221fa10d2 | |
parent | 5bdb091133b98652f366e666c5c8bc4de1513f2b (diff) | |
download | edk2-4bd3b5ab13799765125b5ff2d126bc1565eaedac.tar.gz |
OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654
If the hypervisor supports retrieval of the vCPU APIC IDs, retrieve
them before any APs are actually started. The APIC IDs can be used
to start the APs for any SEV-SNP guest, but is a requirement for an
SEV-SNP guest that is running under an SVSM.
After retrieving the APIC IDs, save the address of the APIC ID data
structure in a GUIDed HOB.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Michael Roth <michael.roth@amd.com>
Cc: Min Xu <min.m.xu@intel.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
-rw-r--r-- | OvmfPkg/PlatformPei/AmdSev.c | 92 | ||||
-rw-r--r-- | OvmfPkg/PlatformPei/PlatformPei.inf | 1 |
2 files changed, 92 insertions, 1 deletions
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c index e6b602d79a..a9de33074a 100644 --- a/OvmfPkg/PlatformPei/AmdSev.c +++ b/OvmfPkg/PlatformPei/AmdSev.c @@ -1,7 +1,7 @@ /**@file
Initialize Secure Encrypted Virtualization (SEV) support
- Copyright (c) 2017 - 2020, Advanced Micro Devices. All rights reserved.<BR>
+ Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -9,6 +9,7 @@ //
// The package level header files this module uses
//
+#include <Guid/GhcbApicIds.h>
#include <IndustryStandard/Q35MchIch9.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
@@ -32,6 +33,87 @@ GetHypervisorFeature ( );
/**
+ Retrieve APIC IDs from the hypervisor.
+
+**/
+STATIC
+VOID
+AmdSevSnpGetApicIds (
+ VOID
+ )
+{
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+ GHCB *Ghcb;
+ BOOLEAN InterruptState;
+ UINT64 VmgExitStatus;
+ UINT64 PageCount;
+ BOOLEAN PageCountValid;
+ VOID *ApicIds;
+ RETURN_STATUS Status;
+ UINT64 GuidData;
+
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ Ghcb = Msr.Ghcb;
+
+ PageCount = 0;
+ PageCountValid = FALSE;
+
+ CcExitVmgInit (Ghcb, &InterruptState);
+ Ghcb->SaveArea.Rax = PageCount;
+ CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
+ VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, 0, 0);
+ if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax)) {
+ PageCount = Ghcb->SaveArea.Rax;
+ PageCountValid = TRUE;
+ }
+
+ CcExitVmgDone (Ghcb, InterruptState);
+
+ ASSERT (VmgExitStatus == 0);
+ ASSERT (PageCountValid);
+ if ((VmgExitStatus != 0) || !PageCountValid) {
+ return;
+ }
+
+ //
+ // Allocate the memory for the APIC IDs
+ //
+ ApicIds = AllocateReservedPages ((UINTN)PageCount);
+ ASSERT (ApicIds != NULL);
+
+ Status = MemEncryptSevClearPageEncMask (
+ 0,
+ (UINTN)ApicIds,
+ (UINTN)PageCount
+ );
+ ASSERT_RETURN_ERROR (Status);
+
+ ZeroMem (ApicIds, EFI_PAGES_TO_SIZE ((UINTN)PageCount));
+
+ PageCountValid = FALSE;
+
+ CcExitVmgInit (Ghcb, &InterruptState);
+ Ghcb->SaveArea.Rax = PageCount;
+ CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
+ VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, (UINTN)ApicIds, 0);
+ if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax) && (Ghcb->SaveArea.Rax == PageCount)) {
+ PageCountValid = TRUE;
+ }
+
+ CcExitVmgDone (Ghcb, InterruptState);
+
+ ASSERT (VmgExitStatus == 0);
+ ASSERT (PageCountValid);
+ if ((VmgExitStatus != 0) || !PageCountValid) {
+ FreePages (ApicIds, (UINTN)PageCount);
+ return;
+ }
+
+ GuidData = (UINT64)(UINTN)ApicIds;
+ BuildGuidDataHob (&gGhcbApicIdsGuid, &GuidData, sizeof (GuidData));
+}
+
+/**
Initialize SEV-SNP support if running as an SEV-SNP guest.
**/
@@ -78,6 +160,14 @@ AmdSevSnpInitialize ( }
}
}
+
+ //
+ // Retrieve the APIC IDs if the hypervisor supports it. These will be used
+ // to always start APs using SNP AP Create.
+ //
+ if ((HvFeatures & GHCB_HV_FEATURES_APIC_ID_LIST) == GHCB_HV_FEATURES_APIC_ID_LIST) {
+ AmdSevSnpGetApicIds ();
+ }
}
/**
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf index ad52be3065..2206316fec 100644 --- a/OvmfPkg/PlatformPei/PlatformPei.inf +++ b/OvmfPkg/PlatformPei/PlatformPei.inf @@ -45,6 +45,7 @@ gEfiMemoryTypeInformationGuid
gFdtHobGuid
gUefiOvmfPkgPlatformInfoGuid
+ gGhcbApicIdsGuid
[LibraryClasses]
BaseLib
|