summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2024-03-08 07:30:33 -0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-04-17 18:30:03 +0000
commit5bdb091133b98652f366e666c5c8bc4de1513f2b (patch)
tree3f4c34314394d9c538ee95a4d04f1f1130775adb
parent8a6471819b55336c88d029149a397791adb2d829 (diff)
downloadedk2-5bdb091133b98652f366e666c5c8bc4de1513f2b.tar.gz
edk2-5bdb091133b98652f366e666c5c8bc4de1513f2b.tar.bz2
edk2-5bdb091133b98652f366e666c5c8bc4de1513f2b.zip
UefiCpuPkg/MpInitLib: Always use AP Create if GhcbApicIds HOB is present
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654 Currently, the first time an AP is started for an SEV-SNP guest, it relies on the VMSA as set by the hypervisor. If the list of APIC IDs has been retrieved, this is not necessary. The list of APIC IDs will be identified by a GUIDed HOB. If the GUIDed HOB is present, use the SEV-SNP AP Create protocol to start the AP for the first time and each time thereafter. 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> Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Acked-by: Ray Ni <ray.ni@intel.com>
-rw-r--r--UefiCpuPkg/Include/Guid/GhcbApicIds.h17
-rw-r--r--UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf1
-rw-r--r--UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c21
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c9
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h15
-rw-r--r--UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf1
-rw-r--r--UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c78
-rw-r--r--UefiCpuPkg/UefiCpuPkg.dec5
8 files changed, 133 insertions, 14 deletions
diff --git a/UefiCpuPkg/Include/Guid/GhcbApicIds.h b/UefiCpuPkg/Include/Guid/GhcbApicIds.h
new file mode 100644
index 0000000000..9d5bfcb0de
--- /dev/null
+++ b/UefiCpuPkg/Include/Guid/GhcbApicIds.h
@@ -0,0 +1,17 @@
+/** @file
+ APIC ID list retrieved for an SEV-ES/SEV-SNP guest via the GHCB.
+
+ Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef GHCB_APIC_IDS_H_
+#define GHCB_APIC_IDS_H_
+
+#define GHCB_APIC_IDS_GUID \
+ { 0xbc964338, 0xee39, 0x4fc8, { 0xa2, 0x24, 0x10, 0x10, 0x8b, 0x17, 0x80, 0x1b }}
+
+extern EFI_GUID gGhcbApicIdsGuid;
+
+#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 407f4988b5..15c10b3060 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -77,6 +77,7 @@
gEfiEventExitBootServicesGuid ## CONSUMES ## Event
gEfiEventLegacyBootGuid ## SOMETIMES_CONSUMES ## Event
gEdkiiMicrocodePatchHobGuid ## SOMETIMES_CONSUMES ## HOB
+ gGhcbApicIdsGuid ## SOMETIMES_CONSUMES ## HOB
[Guids.LoongArch64]
gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
index c83144285b..0478e92317 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
@@ -2,7 +2,7 @@
AMD SEV helper function.
- Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
+ Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -68,3 +68,22 @@ SevSnpRmpAdjust (
//
return RETURN_UNSUPPORTED;
}
+
+/**
+ Determine if the SEV-SNP AP Create protocol should be used.
+
+ @param[in] CpuMpData Pointer to CPU MP Data
+
+ @retval TRUE Use SEV-SNP AP Create protocol
+ @retval FALSE Do not use SEV-SNP AP Create protocol
+**/
+BOOLEAN
+CanUseSevSnpCreateAP (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ //
+ // SEV-SNP is not supported on 32-bit build.
+ //
+ return FALSE;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 9bac62f289..d724456502 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -2,7 +2,7 @@
CPU MP Initialize Library common functions.
Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2020, AMD Inc. All rights reserved.<BR>
+ Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -1303,9 +1303,10 @@ WakeUpAP (
//
// Wakeup all APs
// Must use the INIT-SIPI-SIPI method for initial configuration in
- // order to obtain the APIC ID.
+ // order to obtain the APIC ID if not an SEV-SNP guest and the
+ // list of APIC IDs is not available.
//
- if (CpuMpData->SevSnpIsEnabled && (CpuMpData->InitFlag != ApInitConfig)) {
+ if (CanUseSevSnpCreateAP (CpuMpData)) {
SevSnpCreateAP (CpuMpData, -1);
} else {
if ((CpuMpData->InitFlag == ApInitConfig) && FixedPcdGetBool (PcdFirstTimeWakeUpAPsBySipi)) {
@@ -1415,7 +1416,7 @@ WakeUpAP (
SetSevEsJumpTable (ExchangeInfo->BufferStart);
}
- if (CpuMpData->SevSnpIsEnabled && (CpuMpData->InitFlag != ApInitConfig)) {
+ if (CanUseSevSnpCreateAP (CpuMpData)) {
SevSnpCreateAP (CpuMpData, (INTN)ProcessorNumber);
} else {
SendInitSipiSipi (
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index d26035559f..65e05c4806 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -2,7 +2,7 @@
Common header file for MP Initialize Library.
Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2020, AMD Inc. All rights reserved.<BR>
+ Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -925,6 +925,19 @@ SevSnpCreateAP (
);
/**
+ Determine if the SEV-SNP AP Create protocol should be used.
+
+ @param[in] CpuMpData Pointer to CPU MP Data
+
+ @retval TRUE Use SEV-SNP AP Create protocol
+ @retval FALSE Do not use SEV-SNP AP Create protocol
+**/
+BOOLEAN
+CanUseSevSnpCreateAP (
+ IN CPU_MP_DATA *CpuMpData
+ );
+
+/**
Get pointer to CPU MP Data structure from GUIDed HOB.
@param[in] CpuMpData The pointer to CPU MP Data structure.
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 3ba15c149e..6c75b96fdc 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -85,6 +85,7 @@
[Guids]
gEdkiiS3SmmInitDoneGuid
gEdkiiMicrocodePatchHobGuid
+ gGhcbApicIdsGuid ## SOMETIMES_CONSUMES
[Guids.LoongArch64]
gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
index c9f0984f41..bd12a5ee2f 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
@@ -2,7 +2,7 @@
AMD SEV helper function.
- Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
+ Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -268,20 +268,55 @@ SevSnpCreateAP (
IN INTN ProcessorNumber
)
{
- CPU_INFO_IN_HOB *CpuInfoInHob;
- CPU_AP_DATA *CpuData;
- UINTN Index;
- UINT32 ApicId;
+ CPU_INFO_IN_HOB *CpuInfoInHob;
+ CPU_AP_DATA *CpuData;
+ UINTN Index;
+ UINTN MaxIndex;
+ UINT32 ApicId;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ GHCB_APIC_IDS *GhcbApicIds;
ASSERT (CpuMpData->MpCpuExchangeInfo->BufferStart < 0x100000);
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
if (ProcessorNumber < 0) {
- for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
+ if (CpuMpData->InitFlag == ApInitConfig) {
+ //
+ // APs have not been started, so CpuCount is not "known" yet. Use the
+ // retrieved APIC IDs to start the APs and fill out the MpLib CPU
+ // information properly. CanUseSevSnpCreateAP() guarantees we have a
+ // HOB when InitFlag is ApInitConfig.
+ //
+ GuidHob = GetFirstGuidHob (&gGhcbApicIdsGuid);
+ GhcbApicIds = (GHCB_APIC_IDS *)(*(UINTN *)GET_GUID_HOB_DATA (GuidHob));
+ MaxIndex = MIN (GhcbApicIds->NumEntries, PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ } else {
+ //
+ // APs have been previously started.
+ //
+ MaxIndex = CpuMpData->CpuCount;
+ }
+
+ for (Index = 0; Index < MaxIndex; Index++) {
if (Index != CpuMpData->BspNumber) {
CpuData = &CpuMpData->CpuData[Index];
- ApicId = CpuInfoInHob[Index].ApicId,
+
+ if (CpuMpData->InitFlag == ApInitConfig) {
+ ApicId = GhcbApicIds->ApicIds[Index];
+
+ //
+ // For the first boot, use the BSP register information.
+ //
+ CopyMem (
+ &CpuData->VolatileRegisters,
+ &CpuMpData->CpuData[0].VolatileRegisters,
+ sizeof (CpuData->VolatileRegisters)
+ );
+ } else {
+ ApicId = CpuInfoInHob[Index].ApicId;
+ }
+
SevSnpCreateSaveArea (CpuMpData, CpuData, ApicId);
}
}
@@ -325,3 +360,32 @@ SevSnpRmpAdjust (
return AsmRmpAdjust ((UINT64)PageAddress, 0, Rdx);
}
+
+/**
+ Determine if the SEV-SNP AP Create protocol should be used.
+
+ @param[in] CpuMpData Pointer to CPU MP Data
+
+ @retval TRUE Use SEV-SNP AP Create protocol
+ @retval FALSE Do not use SEV-SNP AP Create protocol
+**/
+BOOLEAN
+CanUseSevSnpCreateAP (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ //
+ // The AP Create protocol is used for an SEV-SNP guest if
+ // - The initial configuration has been performed already or
+ // - The APIC IDs GUIDed HOB is non-zero.
+ //
+ if (!CpuMpData->SevSnpIsEnabled) {
+ return FALSE;
+ }
+
+ if ((CpuMpData->InitFlag == ApInitConfig) && (GetFirstGuidHob (&gGhcbApicIdsGuid) == NULL)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 8ca3b7a5a6..da85e79731 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -2,7 +2,7 @@
# This Package provides UEFI compatible CPU modules and libraries.
#
# Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.<BR>
-# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights reserved.<BR>
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -98,6 +98,9 @@
## Include/Guid/ProcessorResourceHob.h
gProcessorResourceHobGuid = { 0xb855c7fe, 0xa758, 0x701f, { 0xa7, 0x30, 0x87, 0xf3, 0x9c, 0x03, 0x46, 0x7e }}
+ #
+ ## Include/Guid/GhcbApicIds.h
+ gGhcbApicIdsGuid = { 0xbc964338, 0xee39, 0x4fc8, { 0xa2, 0x24, 0x10, 0x10, 0x8b, 0x17, 0x80, 0x1b }}
[Protocols]
## Include/Protocol/SmmCpuService.h