summaryrefslogtreecommitdiff
path: root/UefiCpuPkg
diff options
context:
space:
mode:
authorPhil Noh <Phil.Noh@amd.com>2025-09-02 12:25:13 -0500
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2025-09-04 14:31:57 +0000
commit65485e195f37653bbbc06db2001c3a189d468666 (patch)
tree100e11cf9c692501ec34290693aa4f52d113c88c /UefiCpuPkg
parent1dacf4c40825e184f08be4d3041dc9e2be4d3c5c (diff)
downloadedk2-master.zip
edk2-master.tar.gz
edk2-master.tar.bz2
UefiCpuPkg/MpInitLib: Ensure AP wake up on WakeUpByInitSipiSipi modeHEADmaster
If AP loop mode is not Halt loop, it is found that the AP in ApInitDone state exits the loop mode immediately when WAKEUP_AP_SIGNAL is signaled at the first step of AP wake up. When WakeUpByInitSipiSipi is enabled, it is possible that the AP could clear StartupApSignal buffer before the BSP sends Init-Startup IPI to the AP. In the case, it causes that the BSP frees AP reset vector buffer even though AP wake up is in process. This results in an exception error. To ensure AP wake up, it is expected that the AP is in the known non-executable state before the AP wakeup signal. The issue happens when the AP is disabled through the MP service of gEfiMpServiceProtocolGuid->EnableDisableAP(FALSE) and enabled later through gEfiMpServiceProtocolGuid->EnableDisableAP(TRUE). In the flow, the AP that in MINOTOR-MWAIT-Loop or Run-Loop can respond to the WAKEUP_AP_SIGNAL before the BSP sends the INIT-SIPI-SIPI. Signed-off-by: Phil Noh <Phil.Noh@amd.com>
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf2
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c18
-rw-r--r--UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf2
3 files changed, 20 insertions, 2 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 922c7b1..ab2f1ad 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -3,6 +3,7 @@
#
# Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
+# Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -100,3 +101,4 @@
gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 63b8464..2cf91bf 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 - 2024, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR>
+ Copyright (C) 2020 - 2025 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -1663,12 +1663,26 @@ ResetProcessorToIdleState (
CpuMpData = GetCpuMpData ();
- CpuMpData->WakeUpByInitSipiSipi = TRUE;
if (CpuMpData == NULL) {
DEBUG ((DEBUG_ERROR, "[%a] - Failed to get CpuMpData. Aborting the AP reset to idle.\n", __func__));
return;
}
+ CpuMpData->WakeUpByInitSipiSipi = TRUE;
+
+ //
+ // "CpuMpData->WakeUpByInitSipiSipi = TRUE" requires that the AP must be in Halt loop.
+ // If AP loop mode is not Halt loop, make sure that the AP is in the known non-executable state.
+ //
+ // AP could be in MONITOR/MWAIT state that could wake up the AP when setting WAKEUP_AP_SIGNAL in WakeUpAp().
+ // And then SendInitSipiSipi() in WakeupAp() could wake up the AP again to run the AP Wakeup vector.
+ // But the AP wakeup vector could be freed by the BSP while the AP is running it.
+ //
+ if (CpuMpData->ApLoopMode != ApInHltLoop) {
+ SendInitIpi (((CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob)[ProcessorNumber].ApicId);
+ MicroSecondDelay (PcdGet32 (PcdCpuInitIpiDelayInMicroSeconds));
+ }
+
WakeUpAP (CpuMpData, FALSE, ProcessorNumber, NULL, NULL, TRUE);
while (CpuMpData->FinishedCount < 1) {
CpuPause ();
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index d1e8312..cbef1e8 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -3,6 +3,7 @@
#
# Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
+# Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -83,6 +84,7 @@
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES
[Ppis]
gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES