]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
UefiCpuPkg/PiSmmCpuDxeSmm: Add paging protection.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / MpService.c
index 12466ef5de1f633b20c24bcec75e1ffff0c1e586..9b8db90ff6edb465787c972b250a0133aafc6dfe 100644 (file)
@@ -734,14 +734,12 @@ APHandler (
 /**\r
   Create 4G PageTable in SMRAM.\r
 \r
-  @param          ExtraPages       Additional page numbers besides for 4G memory\r
-  @param          Is32BitPageTable Whether the page table is 32-bit PAE\r
+  @param[in]      Is32BitPageTable Whether the page table is 32-bit PAE\r
   @return         PageTable Address\r
 \r
 **/\r
 UINT32\r
 Gen4GPageTable (\r
-  IN      UINTN                     ExtraPages,\r
   IN      BOOLEAN                   Is32BitPageTable\r
   )\r
 {\r
@@ -775,10 +773,10 @@ Gen4GPageTable (
   //\r
   // Allocate the page table\r
   //\r
-  PageTable = AllocatePageTableMemory (ExtraPages + 5 + PagesNeeded);\r
+  PageTable = AllocatePageTableMemory (5 + PagesNeeded);\r
   ASSERT (PageTable != NULL);\r
 \r
-  PageTable = (VOID *)((UINTN)PageTable + EFI_PAGES_TO_SIZE (ExtraPages));\r
+  PageTable = (VOID *)((UINTN)PageTable);\r
   Pte = (UINT64*)PageTable;\r
 \r
   //\r
@@ -903,13 +901,13 @@ SetCacheability (
   PageTable[PTIndex] |= (UINT64)Cacheability;\r
 }\r
 \r
-\r
 /**\r
   Schedule a procedure to run on the specified CPU.\r
 \r
-  @param  Procedure                The address of the procedure to run\r
-  @param  CpuIndex                 Target CPU Index\r
-  @param  ProcArguments            The parameter to pass to the procedure\r
+  @param[in]       Procedure                The address of the procedure to run\r
+  @param[in]       CpuIndex                 Target CPU Index\r
+  @param[in, OUT]  ProcArguments            The parameter to pass to the procedure\r
+  @param[in]       BlockingMode             Startup AP in blocking mode or not\r
 \r
   @retval EFI_INVALID_PARAMETER    CpuNumber not valid\r
   @retval EFI_INVALID_PARAMETER    CpuNumber specifying BSP\r
@@ -919,32 +917,104 @@ SetCacheability (
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
-SmmStartupThisAp (\r
+InternalSmmStartupThisAp (\r
   IN      EFI_AP_PROCEDURE          Procedure,\r
   IN      UINTN                     CpuIndex,\r
-  IN OUT  VOID                      *ProcArguments OPTIONAL\r
+  IN OUT  VOID                      *ProcArguments OPTIONAL,\r
+  IN      BOOLEAN                   BlockingMode\r
   )\r
 {\r
-  if (CpuIndex >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus ||\r
-      CpuIndex == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu ||\r
-      !(*(mSmmMpSyncData->CpuData[CpuIndex].Present)) ||\r
-      gSmmCpuPrivate->Operation[CpuIndex] == SmmCpuRemove ||\r
-      !AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy)) {\r
+  if (CpuIndex >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus) {\r
+    DEBUG((DEBUG_ERROR, "CpuIndex(%d) >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus(%d)\n", CpuIndex, gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  if (CpuIndex == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) {\r
+    DEBUG((DEBUG_ERROR, "CpuIndex(%d) == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu\n", CpuIndex));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+  if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) {\r
+    if (mSmmMpSyncData->EffectiveSyncMode == SmmCpuSyncModeTradition) {\r
+      DEBUG((DEBUG_ERROR, "!mSmmMpSyncData->CpuData[%d].Present\n", CpuIndex));\r
+    }\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  if (gSmmCpuPrivate->Operation[CpuIndex] == SmmCpuRemove) {\r
+    if (!FeaturePcdGet (PcdCpuHotPlugSupport)) {\r
+      DEBUG((DEBUG_ERROR, "gSmmCpuPrivate->Operation[%d] == SmmCpuRemove\n", CpuIndex));\r
+    }\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (BlockingMode) {\r
+    AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
+  } else {\r
+    if (!AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy)) {\r
+      DEBUG((DEBUG_ERROR, "mSmmMpSyncData->CpuData[%d].Busy\n", CpuIndex));\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
 \r
   mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure;\r
   mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments;\r
   ReleaseSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);\r
 \r
-  if (FeaturePcdGet (PcdCpuSmmBlockStartupThisAp)) {\r
+  if (BlockingMode) {\r
     AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
     ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
   }\r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Schedule a procedure to run on the specified CPU in blocking mode.\r
+\r
+  @param[in]       Procedure                The address of the procedure to run\r
+  @param[in]       CpuIndex                 Target CPU Index\r
+  @param[in, out]  ProcArguments            The parameter to pass to the procedure\r
+\r
+  @retval EFI_INVALID_PARAMETER    CpuNumber not valid\r
+  @retval EFI_INVALID_PARAMETER    CpuNumber specifying BSP\r
+  @retval EFI_INVALID_PARAMETER    The AP specified by CpuNumber did not enter SMM\r
+  @retval EFI_INVALID_PARAMETER    The AP specified by CpuNumber is busy\r
+  @retval EFI_SUCCESS              The procedure has been successfully scheduled\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmBlockingStartupThisAp (\r
+  IN      EFI_AP_PROCEDURE          Procedure,\r
+  IN      UINTN                     CpuIndex,\r
+  IN OUT  VOID                      *ProcArguments OPTIONAL\r
+  )\r
+{\r
+  return InternalSmmStartupThisAp(Procedure, CpuIndex, ProcArguments, TRUE);\r
+}\r
+\r
+/**\r
+  Schedule a procedure to run on the specified CPU.\r
+\r
+  @param  Procedure                The address of the procedure to run\r
+  @param  CpuIndex                 Target CPU Index\r
+  @param  ProcArguments            The parameter to pass to the procedure\r
+\r
+  @retval EFI_INVALID_PARAMETER    CpuNumber not valid\r
+  @retval EFI_INVALID_PARAMETER    CpuNumber specifying BSP\r
+  @retval EFI_INVALID_PARAMETER    The AP specified by CpuNumber did not enter SMM\r
+  @retval EFI_INVALID_PARAMETER    The AP specified by CpuNumber is busy\r
+  @retval EFI_SUCCESS              The procedure has been successfully scheduled\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmStartupThisAp (\r
+  IN      EFI_AP_PROCEDURE          Procedure,\r
+  IN      UINTN                     CpuIndex,\r
+  IN OUT  VOID                      *ProcArguments OPTIONAL\r
+  )\r
+{\r
+  return InternalSmmStartupThisAp(Procedure, CpuIndex, ProcArguments, FeaturePcdGet (PcdCpuSmmBlockStartupThisAp));\r
+}\r
+\r
 /**\r
   This function sets DR6 & DR7 according to SMM save state, before running SMM C code.\r
   They are useful when you want to enable hardware breakpoints in SMM without entry SMM mode.\r
@@ -964,6 +1034,7 @@ CpuSmmDebugEntry (
   SMRAM_SAVE_STATE_MAP *CpuSaveState;\r
   \r
   if (FeaturePcdGet (PcdCpuSmmDebug)) {\r
+    ASSERT(CpuIndex < mMaxNumberOfCpus);\r
     CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmmCpuPrivate->CpuSaveState[CpuIndex];\r
     if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {\r
       AsmWriteDr6 (CpuSaveState->x86._DR6);\r
@@ -993,6 +1064,7 @@ CpuSmmDebugExit (
   SMRAM_SAVE_STATE_MAP *CpuSaveState;\r
 \r
   if (FeaturePcdGet (PcdCpuSmmDebug)) {\r
+    ASSERT(CpuIndex < mMaxNumberOfCpus);\r
     CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmmCpuPrivate->CpuSaveState[CpuIndex];\r
     if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {\r
       CpuSaveState->x86._DR7 = (UINT32)AsmReadDr7 ();\r
@@ -1022,8 +1094,8 @@ SmiRendezvous (
   BOOLEAN                        BspInProgress;\r
   UINTN                          Index;\r
   UINTN                          Cr2;\r
-  BOOLEAN                        XdDisableFlag;\r
-  MSR_IA32_MISC_ENABLE_REGISTER  MiscEnableMsr;\r
+\r
+  ASSERT(CpuIndex < mMaxNumberOfCpus);\r
 \r
   //\r
   // Save Cr2 because Page Fault exception in SMM may override its value\r
@@ -1082,20 +1154,6 @@ SmiRendezvous (
       InitializeSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
     }\r
 \r
-    //\r
-    // Try to enable XD\r
-    //\r
-    XdDisableFlag = FALSE;\r
-    if (mXdSupported) {\r
-      MiscEnableMsr.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE);\r
-      if (MiscEnableMsr.Bits.XD == 1) {\r
-        XdDisableFlag = TRUE;\r
-        MiscEnableMsr.Bits.XD = 0;\r
-        AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, MiscEnableMsr.Uint64);\r
-      }\r
-      ActivateXd ();\r
-    }\r
-\r
     if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {\r
       ActivateSmmProfile (CpuIndex);\r
     }\r
@@ -1176,15 +1234,6 @@ SmiRendezvous (
     //\r
     while (*mSmmMpSyncData->AllCpusInSync) {\r
       CpuPause ();\r
-     }\r
-\r
-    //\r
-    // Restore XD\r
-    //\r
-    if (XdDisableFlag) {\r
-      MiscEnableMsr.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE);\r
-      MiscEnableMsr.Bits.XD = 1;\r
-      AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, MiscEnableMsr.Uint64);\r
     }\r
   }\r
 \r