]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/CpuHotplugSmm/CpuHotplug.c
OvmfPkg/CpuHotplugSmm: collect hot-unplug events
[mirror_edk2.git] / OvmfPkg / CpuHotplugSmm / CpuHotplug.c
index bf68fcd42914188f5c89be1180d687a877c24383..ee1497b931407ed2482fbe3ea8cadf3741c4c818 100644 (file)
@@ -45,13 +45,16 @@ STATIC CPU_HOT_PLUG_DATA *mCpuHotPlugData;
 // don't want to allocate SMRAM at OS runtime, and potentially fail (or\r
 // fragment the SMRAM map).\r
 //\r
-// These arrays provide room for ("possible CPU count" minus one) APIC IDs\r
-// each, as we don't expect every possible CPU to appear, or disappear, in a\r
-// single MMI. The numbers of used (populated) elements in the arrays are\r
+// The first array stores APIC IDs for hot-plug events, the second and the\r
+// third store APIC IDs and QEMU CPU Selectors (both indexed similarly) for\r
+// hot-unplug events. All of these provide room for "possible CPU count" minus\r
+// one elements as we don't expect every possible CPU to appear, or disappear,\r
+// in a single MMI. The numbers of used (populated) elements in the arrays are\r
 // determined on every MMI separately.\r
 //\r
 STATIC APIC_ID *mPluggedApicIds;\r
 STATIC APIC_ID *mToUnplugApicIds;\r
+STATIC UINT32  *mToUnplugSelectors;\r
 //\r
 // Address of the non-SMRAM reserved memory page that contains the Post-SMM Pen\r
 // for hot-added CPUs.\r
@@ -289,6 +292,7 @@ CpuHotplugMmi (
              mPluggedApicIds,\r
              &PluggedCount,\r
              mToUnplugApicIds,\r
+             mToUnplugSelectors,\r
              &ToUnplugCount\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -333,7 +337,9 @@ CpuHotplugEntry (
   )\r
 {\r
   EFI_STATUS Status;\r
+  UINTN      Len;\r
   UINTN      Size;\r
+  UINTN      SizeSel;\r
 \r
   //\r
   // This module should only be included when SMM support is required.\r
@@ -387,8 +393,9 @@ CpuHotplugEntry (
   //\r
   // Allocate the data structures that depend on the possible CPU count.\r
   //\r
-  if (RETURN_ERROR (SafeUintnSub (mCpuHotPlugData->ArrayLength, 1, &Size)) ||\r
-      RETURN_ERROR (SafeUintnMult (sizeof (APIC_ID), Size, &Size))) {\r
+  if (RETURN_ERROR (SafeUintnSub (mCpuHotPlugData->ArrayLength, 1, &Len)) ||\r
+      RETURN_ERROR (SafeUintnMult (sizeof (APIC_ID), Len, &Size)) ||\r
+      RETURN_ERROR (SafeUintnMult (sizeof (UINT32), Len, &SizeSel))) {\r
     Status = EFI_ABORTED;\r
     DEBUG ((DEBUG_ERROR, "%a: invalid CPU_HOT_PLUG_DATA\n", __FUNCTION__));\r
     goto Fatal;\r
@@ -405,6 +412,12 @@ CpuHotplugEntry (
     DEBUG ((DEBUG_ERROR, "%a: MmAllocatePool(): %r\n", __FUNCTION__, Status));\r
     goto ReleasePluggedApicIds;\r
   }\r
+  Status = gMmst->MmAllocatePool (EfiRuntimeServicesData, SizeSel,\r
+                    (VOID **)&mToUnplugSelectors);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "%a: MmAllocatePool(): %r\n", __FUNCTION__, Status));\r
+    goto ReleaseToUnplugApicIds;\r
+  }\r
 \r
   //\r
   // Allocate the Post-SMM Pen for hot-added CPUs.\r
@@ -412,7 +425,7 @@ CpuHotplugEntry (
   Status = SmbaseAllocatePostSmmPen (&mPostSmmPenAddress,\r
              SystemTable->BootServices);\r
   if (EFI_ERROR (Status)) {\r
-    goto ReleaseToUnplugApicIds;\r
+    goto ReleaseToUnplugSelectors;\r
   }\r
 \r
   //\r
@@ -472,6 +485,10 @@ ReleasePostSmmPen:
   SmbaseReleasePostSmmPen (mPostSmmPenAddress, SystemTable->BootServices);\r
   mPostSmmPenAddress = 0;\r
 \r
+ReleaseToUnplugSelectors:\r
+  gMmst->MmFreePool (mToUnplugSelectors);\r
+  mToUnplugSelectors = NULL;\r
+\r
 ReleaseToUnplugApicIds:\r
   gMmst->MmFreePool (mToUnplugApicIds);\r
   mToUnplugApicIds = NULL;\r