OvmfPkg/SmmCpuFeaturesLib: call CPU hot-eject handler

Call the CPU hot-eject handler if one is installed. The condition for
installation is (PcdCpuMaxLogicalProcessorNumber > 1), and there's
a hot-unplug request.

The handler is called from SmmCpuFeaturesRendezvousExit(), which is
in-turn called at the tail-end of SmiRendezvous() after the BSP has
signalled an SMI exit via the "AllCpusInSync" loop.

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>
Message-Id: <20210312062656.2477515-8-ankur.a.arora@oracle.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
Ankur Arora 2021-03-11 22:26:53 -08:00 committed by mergify[bot]
parent b6d5996706
commit af9c77e151
1 changed files with 34 additions and 0 deletions

View File

@ -452,6 +452,40 @@ SmmCpuFeaturesRendezvousExit (
IN UINTN CpuIndex IN UINTN CpuIndex
) )
{ {
//
// We only call the Handler if CPU hot-eject is enabled
// (PcdCpuMaxLogicalProcessorNumber > 1), and hot-eject is needed
// in this SMI exit (otherwise mCpuHotEjectData->Handler is not armed.)
//
if (mCpuHotEjectData != NULL) {
CPU_HOT_EJECT_HANDLER Handler;
//
// As the comment above mentions, mCpuHotEjectData->Handler might be
// written to on the BSP as part of handling of the CPU-ejection.
//
// We know that any initial assignment to mCpuHotEjectData->Handler
// (on the BSP, in the CpuHotplugMmi() context) is ordered-before the
// load below, since it is guaranteed to happen before the
// control-dependency of the BSP's SMI exit signal -- by way of a store
// to AllCpusInSync (on the BSP, in BspHandler()) and the corresponding
// AllCpusInSync loop (on the APs, in SmiRendezvous()) which depends on
// that store.
//
// This guarantees that these pieces of code can never execute
// simultaneously. In addition, we ensure that the following load is
// ordered-after the AllCpusInSync loop by using a MemoryFence() with
// acquire semantics.
//
MemoryFence();
Handler = mCpuHotEjectData->Handler;
if (Handler != NULL) {
Handler (CpuIndex);
}
}
} }
/** /**