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>
---
UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 57 ++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
index 4ac5e8e..6b66c49 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -196,6 +196,56 @@ AllCpusInSmmWithExceptions (
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
@@ -209,9 +259,14 @@ SmmWaitForApArrival (
{
UINT64 Timer;
UINTN Index;
+ BOOLEAN LmceEn;
+ BOOLEAN LmceSignal;
ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
+ LmceEn = IsLmceOsEnabled ();
+ LmceSignal = IsLmceSignaled();
+
//
// 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
@@ -227,7 +282,7 @@ SmmWaitForApArrival (
// Sync with APs 1st timeout
//
for (Timer = StartSyncTimer ();
- !IsSyncTimerTimeout (Timer) &&
+ !IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal) &&
!AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED );
) {
CpuPause ();
--
2.7.0.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Reviewed-by: Jeff Fan <jeff.fan@intel.com> -----Original Message----- From: Dong, Eric Sent: Tuesday, August 01, 2017 3:51 PM To: edk2-devel@lists.01.org Cc: Fan, Jeff; Ni, Ruiyu Subject: [Patch 3/3] 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> --- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 57 ++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 4ac5e8e..6b66c49 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -196,6 +196,56 @@ AllCpusInSmmWithExceptions ( 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 @@ -209,9 +259,14 @@ SmmWaitForApArrival ( { UINT64 Timer; UINTN Index; + BOOLEAN LmceEn; + BOOLEAN LmceSignal; ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus); + LmceEn = IsLmceOsEnabled (); + LmceSignal = IsLmceSignaled(); + // // 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 @@ -227,7 +282,7 @@ SmmWaitForApArrival ( // Sync with APs 1st timeout // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer) && + !IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal) && !AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED ); ) { CpuPause (); -- 2.7.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2025 Red Hat, Inc.