UefiCpuPkg PiSmmCpuDxeSmm: Check LMCE capability when wait for AP.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
This commit is contained in:
Eric Dong 2017-07-20 20:07:46 +08:00
parent 3d6275c113
commit 12c663822d
1 changed files with 56 additions and 1 deletions

View File

@ -196,6 +196,56 @@ AllCpusInSmmWithExceptions (
return TRUE; return TRUE;
} }
/**
Has OS enabled Lmce in the MSR_IA32_MCG_EXT_CTL
@retval TRUE Os enable lmce.
@retval FALSE Os not enable lmce.
**/
BOOLEAN
IsLmceOsEnabled (
VOID
)
{
MSR_IA32_MCG_CAP_REGISTER McgCap;
MSR_IA32_FEATURE_CONTROL_REGISTER FeatureCtrl;
MSR_IA32_MCG_EXT_CTL_REGISTER McgExtCtrl;
McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP);
if (McgCap.Bits.MCG_LMCE_P == 0) {
return FALSE;
}
FeatureCtrl.Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
if (FeatureCtrl.Bits.LmceOn == 0) {
return FALSE;
}
McgExtCtrl.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_EXT_CTL);
return (BOOLEAN) (McgExtCtrl.Bits.LMCE_EN == 1);
}
/**
Return if Local machine check exception signaled.
Indicates (when set) that a local machine check exception was generated. This indicates that the current machine-check event was
delivered to only the logical processor.
@retval TRUE LMCE was signaled.
@retval FALSE LMCE was not signaled.
**/
BOOLEAN
IsLmceSignaled (
VOID
)
{
MSR_IA32_MCG_STATUS_REGISTER McgStatus;
McgStatus.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_STATUS);
return (BOOLEAN) (McgStatus.Bits.LMCE_S == 1);
}
/** /**
Given timeout constraint, wait for all APs to arrive, and insure when this function returns, no AP will execute normal mode code before Given timeout constraint, wait for all APs to arrive, and insure when this function returns, no AP will execute normal mode code before
@ -209,9 +259,14 @@ SmmWaitForApArrival (
{ {
UINT64 Timer; UINT64 Timer;
UINTN Index; UINTN Index;
BOOLEAN LmceEn;
BOOLEAN LmceSignal;
ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus); ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
LmceEn = IsLmceOsEnabled ();
LmceSignal = IsLmceSignaled();
// //
// Platform implementor should choose a timeout value appropriately: // Platform implementor should choose a timeout value appropriately:
// - The timeout value should balance the SMM time constrains and the likelihood that delayed CPUs are excluded in the SMM run. Note // - The timeout value should balance the SMM time constrains and the likelihood that delayed CPUs are excluded in the SMM run. Note
@ -227,7 +282,7 @@ SmmWaitForApArrival (
// Sync with APs 1st timeout // Sync with APs 1st timeout
// //
for (Timer = StartSyncTimer (); for (Timer = StartSyncTimer ();
!IsSyncTimerTimeout (Timer) && !IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal) &&
!AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED ); !AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED );
) { ) {
CpuPause (); CpuPause ();