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
}\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