]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
UefiCpuPkg/PiSmmCpu: Don't allocate Token for SmmStartupThisAp
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / MpService.c
index 6227b2428a1e3e1644ea7bb0e607d7137266aa8e..fd6583f9d172aa2846c2c8f97f59a857110bd6f2 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 SMM MP service implementation\r
 \r
-Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>\r
 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
 \r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
@@ -22,6 +22,7 @@ UINTN                                       mSemaphoreSize;
 SPIN_LOCK                                   *mPFLock = NULL;\r
 SMM_CPU_SYNC_MODE                           mCpuSmmSyncMode;\r
 BOOLEAN                                     mMachineCheckSupported = FALSE;\r
+MM_COMPLETION                               mSmmStartupThisApToken;\r
 \r
 extern UINTN mSmmShadowStackSize;\r
 \r
@@ -1240,9 +1241,26 @@ InternalSmmStartupThisAp (
   mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure;\r
   mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments;\r
   if (Token != NULL) {\r
-    ProcToken= GetFreeToken (1);\r
-    mSmmMpSyncData->CpuData[CpuIndex].Token = ProcToken;\r
-    *Token = (MM_COMPLETION)ProcToken->SpinLock;\r
+    if (Token != &mSmmStartupThisApToken) {\r
+      //\r
+      // When Token points to mSmmStartupThisApToken, this routine is called\r
+      // from SmmStartupThisAp() in non-blocking mode (PcdCpuSmmBlockStartupThisAp == FALSE).\r
+      //\r
+      // In this case, caller wants to startup AP procedure in non-blocking\r
+      // mode and cannot get the completion status from the Token because there\r
+      // is no way to return the Token to caller from SmmStartupThisAp().\r
+      // Caller needs to use its implementation specific way to query the completion status.\r
+      //\r
+      // There is no need to allocate a token for such case so the 3 overheads\r
+      // can be avoided:\r
+      // 1. Call AllocateTokenBuffer() when there is no free token.\r
+      // 2. Get a free token from the token buffer.\r
+      // 3. Call ReleaseToken() in APHandler().\r
+      //\r
+      ProcToken = GetFreeToken (1);\r
+      mSmmMpSyncData->CpuData[CpuIndex].Token = ProcToken;\r
+      *Token = (MM_COMPLETION)ProcToken->SpinLock;\r
+    }\r
   }\r
   mSmmMpSyncData->CpuData[CpuIndex].Status    = CpuStatus;\r
   if (mSmmMpSyncData->CpuData[CpuIndex].Status != NULL) {\r
@@ -1474,8 +1492,6 @@ SmmStartupThisAp (
   IN OUT  VOID                      *ProcArguments OPTIONAL\r
   )\r
 {\r
-  MM_COMPLETION               Token;\r
-\r
   gSmmCpuPrivate->ApWrapperFunc[CpuIndex].Procedure = Procedure;\r
   gSmmCpuPrivate->ApWrapperFunc[CpuIndex].ProcedureArgument = ProcArguments;\r
 \r
@@ -1486,7 +1502,7 @@ SmmStartupThisAp (
     ProcedureWrapper,\r
     CpuIndex,\r
     &gSmmCpuPrivate->ApWrapperFunc[CpuIndex],\r
-    FeaturePcdGet (PcdCpuSmmBlockStartupThisAp) ? NULL : &Token,\r
+    FeaturePcdGet (PcdCpuSmmBlockStartupThisAp) ? NULL : &mSmmStartupThisApToken,\r
     0,\r
     NULL\r
     );\r