diff options
author | Phil Noh <Phil.Noh@amd.com> | 2025-09-02 12:25:13 -0500 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2025-09-04 14:31:57 +0000 |
commit | 65485e195f37653bbbc06db2001c3a189d468666 (patch) | |
tree | 100e11cf9c692501ec34290693aa4f52d113c88c /UefiCpuPkg | |
parent | 1dacf4c40825e184f08be4d3041dc9e2be4d3c5c (diff) | |
download | edk2-master.zip edk2-master.tar.gz edk2-master.tar.bz2 |
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.inf | 2 | ||||
-rw-r--r-- | UefiCpuPkg/Library/MpInitLib/MpLib.c | 18 | ||||
-rw-r--r-- | UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 2 |
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
|