]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MpInitLib: Move the Above1Mb vector allocation to MpInitLibInitialize
authorRay Ni <ray.ni@intel.com>
Sun, 8 May 2022 05:22:49 +0000 (13:22 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 10 Jun 2022 12:15:49 +0000 (12:15 +0000)
The AP vector consists of 2 parts:
1. the initial 16-bit code that should be under 1MB and page aligned.
2. the 32-bit/64-bit code that can be anywhere in the memory with any
   alignment.

The need of part #2 is because the memory under 1MB is temporary
"stolen" for use and will "give" back after all AP wake up. The range
of memory is not marked as code page in page table. CPU may trigger
exception as soon as NX is enabled.

The part #2 memory allocation can be done in the MpInitLibInitialize.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
UefiCpuPkg/Library/MpInitLib/MpLib.c

index a3e89495e100a412f38f51dfc5a0cb3f56e7bc91..8d1f24370a3636e6e936b5df1a4a42fddc5cdbee 100644 (file)
@@ -955,18 +955,6 @@ FillExchangeInfoData (
     Size     -= sizeof (IA32_SEGMENT_DESCRIPTOR);\r
   }\r
 \r
-  //\r
-  // Copy all 32-bit code and 64-bit code into memory with type of\r
-  // EfiBootServicesCode to avoid page fault if NX memory protection is enabled.\r
-  //\r
-  GetApResetVectorSize (&CpuMpData->AddressMap, NULL, &Size);\r
-  CopyMem (\r
-    (VOID *)CpuMpData->WakeupBufferHigh,\r
-    CpuMpData->AddressMap.RendezvousFunnelAddress +\r
-    CpuMpData->AddressMap.ModeTransitionOffset,\r
-    Size\r
-    );\r
-\r
   ExchangeInfo->ModeTransitionMemory = (UINT32)CpuMpData->WakeupBufferHigh;\r
 \r
   ExchangeInfo->ModeHighMemory = ExchangeInfo->ModeTransitionMemory +\r
@@ -1035,21 +1023,24 @@ RestoreWakeupBuffer (
   @param[in, out]  CpuMpData  The pointer to CPU MP Data structure.\r
 **/\r
 VOID\r
-AllocateResetVector (\r
+AllocateResetVectorBelow1Mb (\r
   IN OUT CPU_MP_DATA  *CpuMpData\r
   )\r
 {\r
-  UINTN  ApResetVectorSizeBelow1Mb;\r
-  UINTN  ApResetVectorSizeAbove1Mb;\r
   UINTN  ApResetStackSize;\r
 \r
   if (CpuMpData->WakeupBuffer == (UINTN)-1) {\r
-    GetApResetVectorSize (&CpuMpData->AddressMap, &ApResetVectorSizeBelow1Mb, &ApResetVectorSizeAbove1Mb);\r
-\r
-    CpuMpData->WakeupBuffer      = GetWakeupBuffer (ApResetVectorSizeBelow1Mb);\r
+    CpuMpData->WakeupBuffer      = GetWakeupBuffer (CpuMpData->BackupBufferSize);\r
     CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *)(UINTN)\r
-                                   (CpuMpData->WakeupBuffer + ApResetVectorSizeBelow1Mb - sizeof (MP_CPU_EXCHANGE_INFO));\r
-    CpuMpData->WakeupBufferHigh = AllocateCodeBuffer (ApResetVectorSizeAbove1Mb);\r
+                                   (CpuMpData->WakeupBuffer + CpuMpData->BackupBufferSize - sizeof (MP_CPU_EXCHANGE_INFO));\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "AP Vector: 16-bit = %p/%x, ExchangeInfo = %p/%x\n",\r
+      CpuMpData->WakeupBuffer,\r
+      CpuMpData->BackupBufferSize - sizeof (MP_CPU_EXCHANGE_INFO),\r
+      CpuMpData->MpCpuExchangeInfo,\r
+      sizeof (MP_CPU_EXCHANGE_INFO)\r
+      ));\r
     //\r
     // The AP reset stack is only used by SEV-ES guests. Do not allocate it\r
     // if SEV-ES is not enabled. An SEV-SNP guest is also considered\r
@@ -1148,7 +1139,7 @@ WakeUpAP (
       (CpuMpData->InitFlag   != ApInitDone))\r
   {\r
     ResetVectorRequired = TRUE;\r
-    AllocateResetVector (CpuMpData);\r
+    AllocateResetVectorBelow1Mb (CpuMpData);\r
     AllocateSevEsAPMemory (CpuMpData);\r
     FillExchangeInfoData (CpuMpData);\r
     SaveLocalApicTimerSetting (CpuMpData);\r
@@ -1789,6 +1780,7 @@ MpInitLibInitialize (
   UINT8                    *MonitorBuffer;\r
   UINTN                    Index;\r
   UINTN                    ApResetVectorSizeBelow1Mb;\r
+  UINTN                    ApResetVectorSizeAbove1Mb;\r
   UINTN                    BackupBufferAddr;\r
   UINTN                    ApIdtBase;\r
 \r
@@ -1802,9 +1794,9 @@ MpInitLibInitialize (
   ASSERT (MaxLogicalProcessorNumber != 0);\r
 \r
   AsmGetAddressMap (&AddressMap);\r
-  GetApResetVectorSize (&AddressMap, &ApResetVectorSizeBelow1Mb, NULL);\r
-  ApStackSize       = PcdGet32 (PcdCpuApStackSize);\r
-  ApLoopMode        = GetApLoopMode (&MonitorFilterSize);\r
+  GetApResetVectorSize (&AddressMap, &ApResetVectorSizeBelow1Mb, &ApResetVectorSizeAbove1Mb);\r
+  ApStackSize = PcdGet32 (PcdCpuApStackSize);\r
+  ApLoopMode  = GetApLoopMode (&MonitorFilterSize);\r
 \r
   //\r
   // Save BSP's Control registers for APs.\r
@@ -1913,6 +1905,19 @@ MpInitLibInitialize (
       (UINT32 *)(MonitorBuffer + MonitorFilterSize * Index);\r
   }\r
 \r
+  //\r
+  // Copy all 32-bit code and 64-bit code into memory with type of\r
+  // EfiBootServicesCode to avoid page fault if NX memory protection is enabled.\r
+  //\r
+  CpuMpData->WakeupBufferHigh = AllocateCodeBuffer (ApResetVectorSizeAbove1Mb);\r
+  CopyMem (\r
+    (VOID *)CpuMpData->WakeupBufferHigh,\r
+    CpuMpData->AddressMap.RendezvousFunnelAddress +\r
+    CpuMpData->AddressMap.ModeTransitionOffset,\r
+    ApResetVectorSizeAbove1Mb\r
+    );\r
+  DEBUG ((DEBUG_INFO, "AP Vector: non-16-bit = %p/%x\n", CpuMpData->WakeupBufferHigh, ApResetVectorSizeAbove1Mb));\r
+\r
   //\r
   // Enable the local APIC for Virtual Wire Mode.\r
   //\r