]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/CpuHotplugSmm: introduce UnplugCpus()
authorAnkur Arora <ankur.a.arora@oracle.com>
Fri, 12 Mar 2021 06:26:50 +0000 (22:26 -0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 16 Mar 2021 13:21:46 +0000 (13:21 +0000)
Introduce UnplugCpus() which maps each APIC ID being unplugged
onto the hardware ID of the processor and informs PiSmmCpuDxeSmm
of removal by calling EFI_SMM_CPU_SERVICE_PROTOCOL.RemoveProcessor().

With this change we handle the first phase of unplug where we collect
the CPUs that need to be unplugged and mark them for removal in SMM
data structures.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Aaron Young <aaron.young@oracle.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3132
Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20210312062656.2477515-5-ankur.a.arora@oracle.com>

OvmfPkg/CpuHotplugSmm/CpuHotplug.c

index ee1497b931407ed2482fbe3ea8cadf3741c4c818..59f000eb788678894c1f6d92c1c26441a19a6b51 100644 (file)
@@ -189,6 +189,83 @@ RevokeNewSlot:
   return Status;\r
 }\r
 \r
+/**\r
+  Process to be hot-unplugged CPUs, per QemuCpuhpCollectApicIds().\r
+\r
+  For each such CPU, report the CPU to PiSmmCpuDxeSmm via\r
+  EFI_SMM_CPU_SERVICE_PROTOCOL. If the to be hot-unplugged CPU is\r
+  unknown, skip it silently.\r
+\r
+  @param[in] ToUnplugApicIds    The APIC IDs of the CPUs that are about to be\r
+                                hot-unplugged.\r
+\r
+  @param[in] ToUnplugCount      The number of filled-in APIC IDs in\r
+                                ToUnplugApicIds.\r
+\r
+  @retval EFI_SUCCESS           Known APIC IDs have been removed from SMM data\r
+                                structures.\r
+\r
+  @return                       Error codes propagated from\r
+                                mMmCpuService->RemoveProcessor().\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+UnplugCpus (\r
+  IN APIC_ID                      *ToUnplugApicIds,\r
+  IN UINT32                       ToUnplugCount\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  UINT32     ToUnplugIdx;\r
+  UINTN      ProcessorNum;\r
+\r
+  ToUnplugIdx = 0;\r
+  while (ToUnplugIdx < ToUnplugCount) {\r
+    APIC_ID    RemoveApicId;\r
+\r
+    RemoveApicId = ToUnplugApicIds[ToUnplugIdx];\r
+\r
+    //\r
+    // mCpuHotPlugData->ApicId maps ProcessorNum -> ApicId. Use it to find\r
+    // the ProcessorNum for the APIC ID to be removed.\r
+    //\r
+    for (ProcessorNum = 0;\r
+         ProcessorNum < mCpuHotPlugData->ArrayLength;\r
+         ProcessorNum++) {\r
+      if (mCpuHotPlugData->ApicId[ProcessorNum] == RemoveApicId) {\r
+        break;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Ignore the unplug if APIC ID not found\r
+    //\r
+    if (ProcessorNum == mCpuHotPlugData->ArrayLength) {\r
+      DEBUG ((DEBUG_VERBOSE, "%a: did not find APIC ID " FMT_APIC_ID\r
+        " to unplug\n", __FUNCTION__, RemoveApicId));\r
+      ToUnplugIdx++;\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Mark ProcessorNum for removal from SMM data structures\r
+    //\r
+    Status = mMmCpuService->RemoveProcessor (mMmCpuService, ProcessorNum);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "%a: RemoveProcessor(" FMT_APIC_ID "): %r\n",\r
+        __FUNCTION__, RemoveApicId, Status));\r
+      return Status;\r
+    }\r
+\r
+    ToUnplugIdx++;\r
+  }\r
+\r
+  //\r
+  // We've removed this set of APIC IDs from SMM data structures.\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   CPU Hotplug MMI handler function.\r
 \r
@@ -311,6 +388,13 @@ CpuHotplugMmi (
     }\r
   }\r
 \r
+  if (ToUnplugCount > 0) {\r
+    Status = UnplugCpus (mToUnplugApicIds, ToUnplugCount);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Fatal;\r
+    }\r
+  }\r
+\r
   //\r
   // We've handled this MMI.\r
   //\r