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 <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>
This commit is contained in:
Ankur Arora 2021-03-11 22:26:50 -08:00 committed by mergify[bot]
parent 2d92e052c3
commit 15e6ae8ea4
1 changed files with 84 additions and 0 deletions

View File

@ -189,6 +189,83 @@ RevokeNewSlot:
return Status; 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. 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. // We've handled this MMI.
// //