mirror of https://github.com/acidanthera/audk.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 <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:
parent
2d92e052c3
commit
15e6ae8ea4
|
@ -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.
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue