UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

Use the SEV-SNP AP Creation NAE event to create and launch APs under
SEV-SNP. This capability will be advertised in the SEV Hypervisor
Feature Support PCD (PcdSevEsHypervisorFeatures).

Cc: Michael Roth <michael.roth@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.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>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
This commit is contained in:
Tom Lendacky
2021-12-09 11:28:00 +08:00
committed by mergify[bot]
parent 67484aed69
commit 06544455d0
7 changed files with 433 additions and 22 deletions

View File

@@ -295,10 +295,12 @@ GetApLoopMode (
ApLoopMode = ApInHltLoop;
}
if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) {
if (ConfidentialComputingGuestHas (CCAttrAmdSevEs) &&
!ConfidentialComputingGuestHas (CCAttrAmdSevSnp))
{
//
// For SEV-ES, force AP in Hlt-loop mode in order to use the GHCB
// protocol for starting APs
// For SEV-ES (SEV-SNP is also considered SEV-ES), force AP in Hlt-loop
// mode in order to use the GHCB protocol for starting APs
//
ApLoopMode = ApInHltLoop;
}
@@ -763,7 +765,7 @@ ApWakeupFunction (
// to allow the APs to issue an AP_RESET_HOLD before the BSP possibly
// performs another INIT-SIPI-SIPI sequence.
//
if (!CpuMpData->SevEsIsEnabled) {
if (!CpuMpData->UseSevEsAPMethod) {
InterlockedDecrement ((UINT32 *)&CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
}
}
@@ -777,7 +779,7 @@ ApWakeupFunction (
//
while (TRUE) {
DisableInterrupts ();
if (CpuMpData->SevEsIsEnabled) {
if (CpuMpData->UseSevEsAPMethod) {
SevEsPlaceApHlt (CpuMpData);
} else {
CpuSleep ();
@@ -1061,9 +1063,13 @@ AllocateResetVector (
);
//
// The AP reset stack is only used by SEV-ES guests. Do not allocate it
// if SEV-ES is not enabled.
// if SEV-ES is not enabled. An SEV-SNP guest is also considered
// an SEV-ES guest, but uses a different method of AP startup, eliminating
// the need for the allocation.
//
if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) {
if (ConfidentialComputingGuestHas (CCAttrAmdSevEs) &&
!ConfidentialComputingGuestHas (CCAttrAmdSevSnp))
{
//
// Stack location is based on ProcessorNumber, so use the total number
// of processors for calculating the total stack area.
@@ -1114,7 +1120,7 @@ FreeResetVector (
// perform the restore as this will overwrite memory which has data
// needed by SEV-ES.
//
if (!CpuMpData->SevEsIsEnabled) {
if (!CpuMpData->UseSevEsAPMethod) {
RestoreWakeupBuffer (CpuMpData);
}
}
@@ -1193,7 +1199,7 @@ WakeUpAP (
if (ResetVectorRequired) {
//
// For SEV-ES, the initial AP boot address will be defined by
// For SEV-ES and SEV-SNP, the initial AP boot address will be defined by
// PcdSevEsWorkAreaBase. The Segment/Rip must be the jump address
// from the original INIT-SIPI-SIPI.
//
@@ -1203,8 +1209,14 @@ WakeUpAP (
//
// Wakeup all APs
// Must use the INIT-SIPI-SIPI method for initial configuration in
// order to obtain the APIC ID.
//
SendInitSipiSipiAllExcludingSelf ((UINT32)ExchangeInfo->BufferStart);
if (CpuMpData->SevSnpIsEnabled && (CpuMpData->InitFlag != ApInitConfig)) {
SevSnpCreateAP (CpuMpData, -1);
} else {
SendInitSipiSipiAllExcludingSelf ((UINT32)ExchangeInfo->BufferStart);
}
}
if (CpuMpData->InitFlag == ApInitConfig) {
@@ -1295,7 +1307,7 @@ WakeUpAP (
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
//
// For SEV-ES, the initial AP boot address will be defined by
// For SEV-ES and SEV-SNP, the initial AP boot address will be defined by
// PcdSevEsWorkAreaBase. The Segment/Rip must be the jump address
// from the original INIT-SIPI-SIPI.
//
@@ -1303,10 +1315,14 @@ WakeUpAP (
SetSevEsJumpTable (ExchangeInfo->BufferStart);
}
SendInitSipiSipi (
CpuInfoInHob[ProcessorNumber].ApicId,
(UINT32)ExchangeInfo->BufferStart
);
if (CpuMpData->SevSnpIsEnabled && (CpuMpData->InitFlag != ApInitConfig)) {
SevSnpCreateAP (CpuMpData, (INTN)ProcessorNumber);
} else {
SendInitSipiSipi (
CpuInfoInHob[ProcessorNumber].ApicId,
(UINT32)ExchangeInfo->BufferStart
);
}
}
//
@@ -1855,10 +1871,15 @@ MpInitLibInitialize (
CpuMpData->CpuData = (CPU_AP_DATA *)(CpuMpData + 1);
CpuMpData->CpuInfoInHob = (UINT64)(UINTN)(CpuMpData->CpuData + MaxLogicalProcessorNumber);
InitializeSpinLock (&CpuMpData->MpLock);
CpuMpData->SevEsIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevEs);
CpuMpData->SevSnpIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevSnp);
CpuMpData->SevEsAPBuffer = (UINTN)-1;
CpuMpData->GhcbBase = PcdGet64 (PcdGhcbBase);
CpuMpData->SevEsIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevEs);
CpuMpData->SevSnpIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevSnp);
CpuMpData->SevEsAPBuffer = (UINTN)-1;
CpuMpData->GhcbBase = PcdGet64 (PcdGhcbBase);
CpuMpData->UseSevEsAPMethod = CpuMpData->SevEsIsEnabled && !CpuMpData->SevSnpIsEnabled;
if (CpuMpData->SevSnpIsEnabled) {
ASSERT ((PcdGet64 (PcdGhcbHypervisorFeatures) & GHCB_HV_FEATURES_SNP_AP_CREATE) == GHCB_HV_FEATURES_SNP_AP_CREATE);
}
//
// Make sure no memory usage outside of the allocated buffer.