]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg PiSmmCpuDxeSmm: Check LMCE capability when wait for AP.
authorEric Dong <eric.dong@intel.com>
Thu, 20 Jul 2017 12:07:46 +0000 (20:07 +0800)
committerEric Dong <eric.dong@intel.com>
Fri, 4 Aug 2017 00:49:05 +0000 (08:49 +0800)
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>
UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c

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