]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.c
MpInitLib: Only allocate below 1MB memory for 16bit code
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.c
index aa0eb9a70b0b10996d0c181b6d233f2058674372..a3e89495e100a412f38f51dfc5a0cb3f56e7bc91 100644 (file)
@@ -848,6 +848,30 @@ WaitApWakeup (
   }\r
 }\r
 \r
+/**\r
+  Calculate the size of the reset vector.\r
+\r
+  @param[in]  AddressMap   The pointer to Address Map structure.\r
+  @param[out] SizeBelow1Mb Return the size of below 1MB memory for AP reset area.\r
+  @param[out] SizeAbove1Mb Return the size of abvoe 1MB memory for AP reset area.\r
+**/\r
+STATIC\r
+VOID\r
+GetApResetVectorSize (\r
+  IN  MP_ASSEMBLY_ADDRESS_MAP  *AddressMap,\r
+  OUT UINTN                    *SizeBelow1Mb OPTIONAL,\r
+  OUT UINTN                    *SizeAbove1Mb OPTIONAL\r
+  )\r
+{\r
+  if (SizeBelow1Mb != NULL) {\r
+    *SizeBelow1Mb = AddressMap->ModeTransitionOffset + sizeof (MP_CPU_EXCHANGE_INFO);\r
+  }\r
+\r
+  if (SizeAbove1Mb != NULL) {\r
+    *SizeAbove1Mb = AddressMap->RendezvousFunnelSize - AddressMap->ModeTransitionOffset;\r
+  }\r
+}\r
+\r
 /**\r
   This function will fill the exchange info structure.\r
 \r
@@ -935,21 +959,15 @@ FillExchangeInfoData (
   // 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
-  if (CpuMpData->WakeupBufferHigh != 0) {\r
-    Size = CpuMpData->AddressMap.RendezvousFunnelSize -\r
-           CpuMpData->AddressMap.ModeTransitionOffset;\r
-    CopyMem (\r
-      (VOID *)CpuMpData->WakeupBufferHigh,\r
-      CpuMpData->AddressMap.RendezvousFunnelAddress +\r
-      CpuMpData->AddressMap.ModeTransitionOffset,\r
-      Size\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
-  } else {\r
-    ExchangeInfo->ModeTransitionMemory = (UINT32)\r
-                                         (ExchangeInfo->BufferStart + CpuMpData->AddressMap.ModeTransitionOffset);\r
-  }\r
+  ExchangeInfo->ModeTransitionMemory = (UINT32)CpuMpData->WakeupBufferHigh;\r
 \r
   ExchangeInfo->ModeHighMemory = ExchangeInfo->ModeTransitionMemory +\r
                                  (UINT32)ExchangeInfo->ModeOffset -\r
@@ -990,7 +1008,7 @@ BackupAndPrepareWakeupBuffer (
   CopyMem (\r
     (VOID *)CpuMpData->WakeupBuffer,\r
     (VOID *)CpuMpData->AddressMap.RendezvousFunnelAddress,\r
-    CpuMpData->AddressMap.RendezvousFunnelSize\r
+    CpuMpData->BackupBufferSize - sizeof (MP_CPU_EXCHANGE_INFO)\r
     );\r
 }\r
 \r
@@ -1011,27 +1029,6 @@ RestoreWakeupBuffer (
     );\r
 }\r
 \r
-/**\r
-  Calculate the size of the reset vector.\r
-\r
-  @param[in]  AddressMap  The pointer to Address Map structure.\r
-\r
-  @return                 Total amount of memory required for the AP reset area\r
-**/\r
-STATIC\r
-UINTN\r
-GetApResetVectorSize (\r
-  IN MP_ASSEMBLY_ADDRESS_MAP  *AddressMap\r
-  )\r
-{\r
-  UINTN  Size;\r
-\r
-  Size = AddressMap->RendezvousFunnelSize +\r
-         sizeof (MP_CPU_EXCHANGE_INFO);\r
-\r
-  return Size;\r
-}\r
-\r
 /**\r
   Allocate reset vector buffer.\r
 \r
@@ -1042,20 +1039,17 @@ AllocateResetVector (
   IN OUT CPU_MP_DATA  *CpuMpData\r
   )\r
 {\r
-  UINTN  ApResetVectorSize;\r
+  UINTN  ApResetVectorSizeBelow1Mb;\r
+  UINTN  ApResetVectorSizeAbove1Mb;\r
   UINTN  ApResetStackSize;\r
 \r
   if (CpuMpData->WakeupBuffer == (UINTN)-1) {\r
-    ApResetVectorSize = GetApResetVectorSize (&CpuMpData->AddressMap);\r
+    GetApResetVectorSize (&CpuMpData->AddressMap, &ApResetVectorSizeBelow1Mb, &ApResetVectorSizeAbove1Mb);\r
 \r
-    CpuMpData->WakeupBuffer      = GetWakeupBuffer (ApResetVectorSize);\r
+    CpuMpData->WakeupBuffer      = GetWakeupBuffer (ApResetVectorSizeBelow1Mb);\r
     CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *)(UINTN)\r
-                                   (CpuMpData->WakeupBuffer +\r
-                                    CpuMpData->AddressMap.RendezvousFunnelSize);\r
-    CpuMpData->WakeupBufferHigh = AllocateCodeBuffer (\r
-                                    CpuMpData->AddressMap.RendezvousFunnelSize -\r
-                                    CpuMpData->AddressMap.ModeTransitionOffset\r
-                                    );\r
+                                   (CpuMpData->WakeupBuffer + ApResetVectorSizeBelow1Mb - sizeof (MP_CPU_EXCHANGE_INFO));\r
+    CpuMpData->WakeupBufferHigh = AllocateCodeBuffer (ApResetVectorSizeAbove1Mb);\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
@@ -1794,7 +1788,7 @@ MpInitLibInitialize (
   UINT8                    ApLoopMode;\r
   UINT8                    *MonitorBuffer;\r
   UINTN                    Index;\r
-  UINTN                    ApResetVectorSize;\r
+  UINTN                    ApResetVectorSizeBelow1Mb;\r
   UINTN                    BackupBufferAddr;\r
   UINTN                    ApIdtBase;\r
 \r
@@ -1808,7 +1802,7 @@ MpInitLibInitialize (
   ASSERT (MaxLogicalProcessorNumber != 0);\r
 \r
   AsmGetAddressMap (&AddressMap);\r
-  ApResetVectorSize = GetApResetVectorSize (&AddressMap);\r
+  GetApResetVectorSize (&AddressMap, &ApResetVectorSizeBelow1Mb, NULL);\r
   ApStackSize       = PcdGet32 (PcdCpuApStackSize);\r
   ApLoopMode        = GetApLoopMode (&MonitorFilterSize);\r
 \r
@@ -1819,7 +1813,7 @@ MpInitLibInitialize (
 \r
   BufferSize  = ApStackSize * MaxLogicalProcessorNumber;\r
   BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber;\r
-  BufferSize += ApResetVectorSize;\r
+  BufferSize += ApResetVectorSizeBelow1Mb;\r
   BufferSize  = ALIGN_VALUE (BufferSize, 8);\r
   BufferSize += VolatileRegisters.Idtr.Limit + 1;\r
   BufferSize += sizeof (CPU_MP_DATA);\r
@@ -1852,12 +1846,12 @@ MpInitLibInitialize (
   //\r
   MonitorBuffer               = (UINT8 *)(Buffer + ApStackSize * MaxLogicalProcessorNumber);\r
   BackupBufferAddr            = (UINTN)MonitorBuffer + MonitorFilterSize * MaxLogicalProcessorNumber;\r
-  ApIdtBase                   = ALIGN_VALUE (BackupBufferAddr + ApResetVectorSize, 8);\r
+  ApIdtBase                   = ALIGN_VALUE (BackupBufferAddr + ApResetVectorSizeBelow1Mb, 8);\r
   CpuMpData                   = (CPU_MP_DATA *)(ApIdtBase + VolatileRegisters.Idtr.Limit + 1);\r
   CpuMpData->Buffer           = Buffer;\r
   CpuMpData->CpuApStackSize   = ApStackSize;\r
   CpuMpData->BackupBuffer     = BackupBufferAddr;\r
-  CpuMpData->BackupBufferSize = ApResetVectorSize;\r
+  CpuMpData->BackupBufferSize = ApResetVectorSizeBelow1Mb;\r
   CpuMpData->WakeupBuffer     = (UINTN)-1;\r
   CpuMpData->CpuCount         = 1;\r
   CpuMpData->BspNumber        = 0;\r