]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MpInitLib: Only allocate below 1MB memory for 16bit code
authorRay Ni <ray.ni@intel.com>
Sat, 7 May 2022 14:25:19 +0000 (22:25 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 10 Jun 2022 12:15:49 +0000 (12:15 +0000)
Today's implementation allocates below 1MB memory for the 16bit, 32bit
and 64bit code.

But it's not necessary since now the 32bit and 64bit code run at high
memory no matter in PEI and DXE phase.

The patch simplifies the logic to remove the code that handles the
case when WakeupBufferHigh is 0.
It also reduce the memory foot print under 1MB by allocating
memory for 16bit code only.

MP_CPU_EXCHANGE_INFO is still under 1MB which is immediate
after the 16bit code.

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

index b4a344ee6b3363d4c5d20365dabf55f26d0dca15..4e4c63a52de40cedcb110b1219e47c125c5937eb 100644 (file)
@@ -110,11 +110,7 @@ MpInitLibSevEsAPReset (
   Code16 = GetProtectedMode16CS ();\r
   Code32 = GetProtectedMode32CS ();\r
 \r
-  if (CpuMpData->WakeupBufferHigh != 0) {\r
-    APResetFn = (AP_RESET *)(CpuMpData->WakeupBufferHigh + CpuMpData->AddressMap.SwitchToRealNoNxOffset);\r
-  } else {\r
-    APResetFn = (AP_RESET *)(CpuMpData->MpCpuExchangeInfo->BufferStart + CpuMpData->AddressMap.SwitchToRealOffset);\r
-  }\r
+  APResetFn = (AP_RESET *)(CpuMpData->WakeupBufferHigh + CpuMpData->AddressMap.SwitchToRealNoNxOffset);\r
 \r
   BufferStart = CpuMpData->MpCpuExchangeInfo->BufferStart;\r
   StackStart  = CpuMpData->SevEsAPResetStackStart -\r
index 1cc071cf7bdd8b43b2929f2a6f333bfe4e884e61..ebadcc6fb3917c01b3d9aa38d286451747118d69 100644 (file)
@@ -95,5 +95,5 @@ struc MP_CPU_EXCHANGE_INFO
   .ExtTopoAvail:                 CTYPE_BOOLEAN 1\r
 endstruc\r
 \r
-MP_CPU_EXCHANGE_INFO_OFFSET equ (SwitchToRealProcEnd - RendezvousFunnelProcStart)\r
+MP_CPU_EXCHANGE_INFO_OFFSET equ (Flat32Start - RendezvousFunnelProcStart)\r
 %define MP_CPU_EXCHANGE_INFO_FIELD(Field) (MP_CPU_EXCHANGE_INFO_OFFSET + MP_CPU_EXCHANGE_INFO. %+ Field)\r
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