summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2024-03-08 07:32:44 -0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-04-17 20:04:41 +0000
commita010681f74c9110a9e8e1753a98c13743b60f7f7 (patch)
tree5bc789e9e3e37fe2a3d770bd8bcdcc38bd4b066f
parent28fecae8a39268e1e21ec1845f3f1e0176db1aa7 (diff)
downloadedk2-a010681f74c9110a9e8e1753a98c13743b60f7f7.tar.gz
edk2-a010681f74c9110a9e8e1753a98c13743b60f7f7.tar.bz2
edk2-a010681f74c9110a9e8e1753a98c13743b60f7f7.zip
UefiCpuPkg/MpInitLib: AP creation support under an SVSM
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654 When running under an SVSM, the VMPL level of the APs that are started must match the VMPL level provided by the SVSM. Additionally, each AP must have a Calling Area for use with the SVSM protocol. Update the AP creation to properly support running under an SVSM. Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Ray Ni <ray.ni@intel.com> Acked-by: Ray Ni <ray.ni@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
-rw-r--r--UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
index 9811356213..bbdc47b5a3 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
@@ -44,7 +44,8 @@ SevSnpPerformApAction (
if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
//
- // Turn the page into a recognized VMSA page.
+ // Turn the page into a recognized VMSA page. When an SVSM is present
+ // the page following the VMSA is the Calling Area page.
//
VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, TRUE);
if (EFI_ERROR (VmsaStatus)) {
@@ -56,6 +57,7 @@ SevSnpPerformApAction (
}
ExitInfo1 = (UINT64)ApicId << 32;
+ ExitInfo1 |= (UINT64)SaveArea->Vmpl << 16;
ExitInfo1 |= Action;
ExitInfo2 = (UINT64)(UINTN)SaveArea;
@@ -87,8 +89,9 @@ SevSnpPerformApAction (
if (Action == SVM_VMGEXIT_SNP_AP_DESTROY) {
//
- // Make the current VMSA not runnable and accessible to be
- // reprogrammed.
+ // Make the current VMSA not runnable and accessible to be reprogrammed.
+ // When an SVSM is present the page following the VMSA is the Calling Area
+ // page.
//
VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, FALSE);
if (EFI_ERROR (VmsaStatus)) {
@@ -116,6 +119,7 @@ SevSnpCreateSaveArea (
UINT32 ApicId
)
{
+ UINTN PageCount;
UINT8 *Pages;
SEV_ES_SAVE_AREA *SaveArea;
IA32_CR0 ApCr0;
@@ -125,13 +129,19 @@ SevSnpCreateSaveArea (
UINTN StartIp;
UINT8 SipiVector;
+ //
+ // When running under an SVSM, a Calling Area page is also needed and is
+ // always the page following the VMSA.
+ //
+ PageCount = AmdSvsmIsSvsmPresent () ? 2 : 1;
+
if (CpuData->SevEsSaveArea == NULL) {
//
// Allocate a page for the SEV-ES Save Area and initialize it. Due to AMD
// erratum #1467 (VMSA cannot be on a 2MB boundary), allocate an extra page
// to choose from to work around the issue.
//
- Pages = AllocateReservedPages (2);
+ Pages = AllocateReservedPages (PageCount + 1);
if (!Pages) {
return;
}
@@ -140,12 +150,12 @@ SevSnpCreateSaveArea (
// Since page allocation works by allocating downward in the address space,
// try to always free the first (lower address) page to limit possible holes
// in the memory map. So, if the address of the second page is 2MB aligned,
- // then use the first page and free the second page. Otherwise, free the
+ // then use the first page and free the last page. Otherwise, free the
// first page and use the second page.
//
if (_IS_ALIGNED (Pages + EFI_PAGE_SIZE, SIZE_2MB)) {
SaveArea = (SEV_ES_SAVE_AREA *)Pages;
- FreePages (Pages + EFI_PAGE_SIZE, 1);
+ FreePages (Pages + (EFI_PAGE_SIZE * PageCount), 1);
} else {
SaveArea = (SEV_ES_SAVE_AREA *)(Pages + EFI_PAGE_SIZE);
FreePages (Pages, 1);
@@ -163,7 +173,7 @@ SevSnpCreateSaveArea (
}
}
- ZeroMem (SaveArea, EFI_PAGE_SIZE);
+ ZeroMem (SaveArea, EFI_PAGE_SIZE * PageCount);
//
// Propogate the CR0.NW and CR0.CD setting to the AP
@@ -239,10 +249,10 @@ SevSnpCreateSaveArea (
//
// Set the SEV-SNP specific fields for the save area:
- // VMPL - always VMPL0
+ // VMPL - based on current mode
// SEV_FEATURES - equivalent to the SEV_STATUS MSR right shifted 2 bits
//
- SaveArea->Vmpl = 0;
+ SaveArea->Vmpl = AmdSvsmSnpGetVmpl ();
SaveArea->SevFeatures = AsmReadMsr64 (MSR_SEV_STATUS) >> 2;
SevSnpPerformApAction (SaveArea, ApicId, SVM_VMGEXIT_SNP_AP_CREATE);