UefiCpuPkg/PiSmmCpuDxeSmm: Optimize Semaphore Sync between BSP and AP

This patch is to define 3 new functions (WaitForBsp & ReleaseBsp &
ReleaseOneAp) used for the semaphore sync between BSP & AP. With the
change, BSP and AP Sync flow will be easy understand as below:
BSP: ReleaseAllAPs or ReleaseOneAp --> AP: WaitForBsp
BSP: WaitForAllAPs                 <-- AP: ReleaseBsp

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Zeng Star <star.zeng@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
Jiaxin Wu 2023-09-21 20:15:44 +08:00 committed by mergify[bot]
parent 8c1e9f9c6f
commit e14a022246
1 changed files with 58 additions and 14 deletions

View File

@ -122,6 +122,7 @@ LockdownSemaphore (
} }
/** /**
Used for BSP to wait all APs.
Wait all APs to performs an atomic compare exchange operation to release semaphore. Wait all APs to performs an atomic compare exchange operation to release semaphore.
@param NumberOfAPs AP number @param NumberOfAPs AP number
@ -141,6 +142,7 @@ WaitForAllAPs (
} }
/** /**
Used for BSP to release all APs.
Performs an atomic compare exchange operation to release semaphore Performs an atomic compare exchange operation to release semaphore
for each AP. for each AP.
@ -159,6 +161,48 @@ ReleaseAllAPs (
} }
} }
/**
Used for BSP to release one AP.
@param ApSem IN: 32-bit unsigned integer
OUT: original integer + 1
**/
VOID
ReleaseOneAp (
IN OUT volatile UINT32 *ApSem
)
{
ReleaseSemaphore (ApSem);
}
/**
Used for AP to wait BSP.
@param ApSem IN: 32-bit unsigned integer
OUT: original integer - 1
**/
VOID
WaitForBsp (
IN OUT volatile UINT32 *ApSem
)
{
WaitForSemaphore (ApSem);
}
/**
Used for AP to release BSP.
@param BspSem IN: 32-bit unsigned integer
OUT: original integer + 1
**/
VOID
ReleaseBsp (
IN OUT volatile UINT32 *BspSem
)
{
ReleaseSemaphore (BspSem);
}
/** /**
Check whether the index of CPU perform the package level register Check whether the index of CPU perform the package level register
programming during System Management Mode initialization. programming during System Management Mode initialization.
@ -634,7 +678,7 @@ BSPHandler (
ReleaseAllAPs (); ReleaseAllAPs ();
// //
// WaitForSemaphore() may wait for ever if an AP happens to enter SMM at // WaitForAllAPs() may wait for ever if an AP happens to enter SMM at
// exactly this point. Please make sure PcdCpuSmmMaxSyncLoops has been set // exactly this point. Please make sure PcdCpuSmmMaxSyncLoops has been set
// to a large enough value to avoid this situation. // to a large enough value to avoid this situation.
// Note: For HT capable CPUs, threads within a core share the same set of MTRRs. // Note: For HT capable CPUs, threads within a core share the same set of MTRRs.
@ -654,7 +698,7 @@ BSPHandler (
ReleaseAllAPs (); ReleaseAllAPs ();
// //
// WaitForSemaphore() may wait for ever if an AP happens to enter SMM at // WaitForAllAPs() may wait for ever if an AP happens to enter SMM at
// exactly this point. Please make sure PcdCpuSmmMaxSyncLoops has been set // exactly this point. Please make sure PcdCpuSmmMaxSyncLoops has been set
// to a large enough value to avoid this situation. // to a large enough value to avoid this situation.
// //
@ -900,14 +944,14 @@ APHandler (
// //
// Notify BSP of arrival at this point // Notify BSP of arrival at this point
// //
ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); ReleaseBsp (mSmmMpSyncData->CpuData[BspIndex].Run);
} }
if (SmmCpuFeaturesNeedConfigureMtrrs ()) { if (SmmCpuFeaturesNeedConfigureMtrrs ()) {
// //
// Wait for the signal from BSP to backup MTRRs // Wait for the signal from BSP to backup MTRRs
// //
WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); WaitForBsp (mSmmMpSyncData->CpuData[CpuIndex].Run);
// //
// Backup OS MTRRs // Backup OS MTRRs
@ -917,12 +961,12 @@ APHandler (
// //
// Signal BSP the completion of this AP // Signal BSP the completion of this AP
// //
ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); ReleaseBsp (mSmmMpSyncData->CpuData[BspIndex].Run);
// //
// Wait for BSP's signal to program MTRRs // Wait for BSP's signal to program MTRRs
// //
WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); WaitForBsp (mSmmMpSyncData->CpuData[CpuIndex].Run);
// //
// Replace OS MTRRs with SMI MTRRs // Replace OS MTRRs with SMI MTRRs
@ -932,14 +976,14 @@ APHandler (
// //
// Signal BSP the completion of this AP // Signal BSP the completion of this AP
// //
ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); ReleaseBsp (mSmmMpSyncData->CpuData[BspIndex].Run);
} }
while (TRUE) { while (TRUE) {
// //
// Wait for something to happen // Wait for something to happen
// //
WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); WaitForBsp (mSmmMpSyncData->CpuData[CpuIndex].Run);
// //
// Check if BSP wants to exit SMM // Check if BSP wants to exit SMM
@ -979,12 +1023,12 @@ APHandler (
// //
// Notify BSP the readiness of this AP to program MTRRs // Notify BSP the readiness of this AP to program MTRRs
// //
ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); ReleaseBsp (mSmmMpSyncData->CpuData[BspIndex].Run);
// //
// Wait for the signal from BSP to program MTRRs // Wait for the signal from BSP to program MTRRs
// //
WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); WaitForBsp (mSmmMpSyncData->CpuData[CpuIndex].Run);
// //
// Restore OS MTRRs // Restore OS MTRRs
@ -996,12 +1040,12 @@ APHandler (
// //
// Notify BSP the readiness of this AP to Reset states/semaphore for this processor // Notify BSP the readiness of this AP to Reset states/semaphore for this processor
// //
ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); ReleaseBsp (mSmmMpSyncData->CpuData[BspIndex].Run);
// //
// Wait for the signal from BSP to Reset states/semaphore for this processor // Wait for the signal from BSP to Reset states/semaphore for this processor
// //
WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); WaitForBsp (mSmmMpSyncData->CpuData[CpuIndex].Run);
// //
// Reset states/semaphore for this processor // Reset states/semaphore for this processor
@ -1011,7 +1055,7 @@ APHandler (
// //
// Notify BSP the readiness of this AP to exit SMM // Notify BSP the readiness of this AP to exit SMM
// //
ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); ReleaseBsp (mSmmMpSyncData->CpuData[BspIndex].Run);
} }
/** /**
@ -1279,7 +1323,7 @@ InternalSmmStartupThisAp (
*mSmmMpSyncData->CpuData[CpuIndex].Status = EFI_NOT_READY; *mSmmMpSyncData->CpuData[CpuIndex].Status = EFI_NOT_READY;
} }
ReleaseSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); ReleaseOneAp (mSmmMpSyncData->CpuData[CpuIndex].Run);
if (Token == NULL) { if (Token == NULL) {
AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy); AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);