summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library
diff options
context:
space:
mode:
authorMichael D Kinney <michael.d.kinney@intel.com>2021-01-23 01:10:20 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-01-26 03:18:40 +0000
commit1c5c7bcd1d06eed7343559ee0da484691d409ab6 (patch)
tree4136118e8cf7c54b3019459558393b338a33408e /UefiCpuPkg/Library
parent3a3501862f73095059bb05cc28147c8e899488f2 (diff)
downloadedk2-1c5c7bcd1d06eed7343559ee0da484691d409ab6.tar.gz
edk2-1c5c7bcd1d06eed7343559ee0da484691d409ab6.tar.bz2
edk2-1c5c7bcd1d06eed7343559ee0da484691d409ab6.zip
UefiCpuPkg/Library/MpInitLib: Fix AP VolatileRegisters race condition
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3182 Fix the order of operations in ApWakeupFunction() when PcdCpuApLoopMode is set to HLT mode that uses INIT-SIPI-SIPI to wake APs. In this mode, volatile state is restored and saved each time a INIT-SIPI-SIPI is sent to an AP to request a function to be executed on the AP. When the function is completed the volatile state of the AP is saved. However, the counters NumApsExecuting and FinishedCount are updated before the volatile state is saved. This allows for a race condition window for the BSP that is waiting on these counters to request a new INIT-SIPI-SIPI before all the APs have completely saved their volatile state. The fix is to save the AP volatile state before updating the NumApsExecuting and FinishedCount counters. Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Diffstat (limited to 'UefiCpuPkg/Library')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 681fa79b4c..8b1f7f84ba 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -769,15 +769,6 @@ ApWakeupFunction (
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack);
ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
-
- //
- // Delay decrementing the APs executing count when SEV-ES is enabled
- // to allow the APs to issue an AP_RESET_HOLD before the BSP possibly
- // performs another INIT-SIPI-SIPI sequence.
- //
- if (!CpuMpData->SevEsIsEnabled) {
- InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
- }
} else {
//
// Execute AP function if AP is ready
@@ -866,20 +857,34 @@ ApWakeupFunction (
}
}
+ if (CpuMpData->ApLoopMode == ApInHltLoop) {
+ //
+ // Save AP volatile registers
+ //
+ SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
+ }
+
//
// AP finished executing C code
//
InterlockedIncrement ((UINT32 *) &CpuMpData->FinishedCount);
+ if (CpuMpData->InitFlag == ApInitConfig) {
+ //
+ // Delay decrementing the APs executing count when SEV-ES is enabled
+ // to allow the APs to issue an AP_RESET_HOLD before the BSP possibly
+ // performs another INIT-SIPI-SIPI sequence.
+ //
+ if (!CpuMpData->SevEsIsEnabled) {
+ InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
+ }
+ }
+
//
// Place AP is specified loop mode
//
if (CpuMpData->ApLoopMode == ApInHltLoop) {
//
- // Save AP volatile registers
- //
- SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
- //
// Place AP in HLT-loop
//
while (TRUE) {