From: Ankur Arora Date: Fri, 12 Mar 2021 06:26:50 +0000 (-0800) Subject: OvmfPkg/CpuHotplugSmm: introduce UnplugCpus() X-Git-Tag: edk2-stable202108~462 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=15e6ae8ea400a55a6bcee8b2b654e5599c05ff18;hp=2d92e052c3afa0aaaa10430a9e2c864907b88079;p=mirror_edk2.git OvmfPkg/CpuHotplugSmm: introduce UnplugCpus() 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 Cc: Jordan Justen Cc: Ard Biesheuvel Cc: Igor Mammedov Cc: Boris Ostrovsky Cc: Aaron Young Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3132 Signed-off-by: Ankur Arora Reviewed-by: Laszlo Ersek Message-Id: <20210312062656.2477515-5-ankur.a.arora@oracle.com> --- diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c index ee1497b931..59f000eb78 100644 --- a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c +++ b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c @@ -189,6 +189,83 @@ RevokeNewSlot: return Status; } +/** + Process to be hot-unplugged CPUs, per QemuCpuhpCollectApicIds(). + + For each such CPU, report the CPU to PiSmmCpuDxeSmm via + EFI_SMM_CPU_SERVICE_PROTOCOL. If the to be hot-unplugged CPU is + unknown, skip it silently. + + @param[in] ToUnplugApicIds The APIC IDs of the CPUs that are about to be + hot-unplugged. + + @param[in] ToUnplugCount The number of filled-in APIC IDs in + ToUnplugApicIds. + + @retval EFI_SUCCESS Known APIC IDs have been removed from SMM data + structures. + + @return Error codes propagated from + mMmCpuService->RemoveProcessor(). +**/ +STATIC +EFI_STATUS +UnplugCpus ( + IN APIC_ID *ToUnplugApicIds, + IN UINT32 ToUnplugCount + ) +{ + EFI_STATUS Status; + UINT32 ToUnplugIdx; + UINTN ProcessorNum; + + ToUnplugIdx = 0; + while (ToUnplugIdx < ToUnplugCount) { + APIC_ID RemoveApicId; + + RemoveApicId = ToUnplugApicIds[ToUnplugIdx]; + + // + // mCpuHotPlugData->ApicId maps ProcessorNum -> ApicId. Use it to find + // the ProcessorNum for the APIC ID to be removed. + // + for (ProcessorNum = 0; + ProcessorNum < mCpuHotPlugData->ArrayLength; + ProcessorNum++) { + if (mCpuHotPlugData->ApicId[ProcessorNum] == RemoveApicId) { + break; + } + } + + // + // Ignore the unplug if APIC ID not found + // + if (ProcessorNum == mCpuHotPlugData->ArrayLength) { + DEBUG ((DEBUG_VERBOSE, "%a: did not find APIC ID " FMT_APIC_ID + " to unplug\n", __FUNCTION__, RemoveApicId)); + ToUnplugIdx++; + continue; + } + + // + // Mark ProcessorNum for removal from SMM data structures + // + Status = mMmCpuService->RemoveProcessor (mMmCpuService, ProcessorNum); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: RemoveProcessor(" FMT_APIC_ID "): %r\n", + __FUNCTION__, RemoveApicId, Status)); + return Status; + } + + ToUnplugIdx++; + } + + // + // We've removed this set of APIC IDs from SMM data structures. + // + return EFI_SUCCESS; +} + /** CPU Hotplug MMI handler function. @@ -311,6 +388,13 @@ CpuHotplugMmi ( } } + if (ToUnplugCount > 0) { + Status = UnplugCpus (mToUnplugApicIds, ToUnplugCount); + if (EFI_ERROR (Status)) { + goto Fatal; + } + } + // // We've handled this MMI. //