On 03/12/21 07:26, Ankur Arora wrote: > @@ -214,6 +243,83 @@ EjectCpu ( > { > UINT64 QemuSelector; > > + if (CheckIfBsp ()) { > + UINT32 Idx; > + > + for (Idx = 0; Idx < mCpuHotEjectData->ArrayLength; Idx++) { > + UINT64 QemuSelector;
Visual Studio warns that the inner QemuSelector declaration shadows the outer one. I'm going to remove the inner declaration, due to: > + > + QemuSelector = mCpuHotEjectData->QemuSelectorMap[Idx]; > + > + if (QemuSelector != CPU_EJECT_QEMU_SELECTOR_INVALID) { > + // > + // This to-be-ejected-CPU has already received the BSP's SMI exit > + // signal and will execute SmmCpuFeaturesRendezvousExit() > + // followed by this callback or is already penned in the > + // CpuSleep() loop below. > + // > + // Tell QEMU to context-switch it out. > + // > + QemuCpuhpWriteCpuSelector (mMmCpuIo, (UINT32) QemuSelector); > + QemuCpuhpWriteCpuStatus (mMmCpuIo, QEMU_CPUHP_STAT_EJECT); > + > + // > + // Now that we've ejected the CPU corresponding to > QemuSelectorMap[Idx], > + // clear its eject status to ensure that an invalid future SMI does > + // not end up trying a spurious eject or a newly hotplugged CPU does > + // not get penned in the CpuSleep() loop. > + // > + // Note that the QemuCpuhpWriteCpuStatus() command above is a write > to > + // a different address space and uses the EFI_MM_CPU_IO_PROTOCOL. > + // > + // This means that we are guaranteed that the following assignment > + // will not be reordered before the eject. And, so we can safely > + // do this write here. > + // > + mCpuHotEjectData->QemuSelectorMap[Idx] = > + CPU_EJECT_QEMU_SELECTOR_INVALID; > + > + DEBUG ((DEBUG_INFO, "%a: Unplugged ProcessorNum %u, " > + "QemuSelector %Lu\n", __FUNCTION__, Idx, QemuSelector)); > + } > + } > + > + // > + // We are done until the next hot-unplug; clear the handler. > + // > + // mCpuHotEjectData->Handler is a NOP for any CPU not under ejection. > + // So, once we are done with all the ejections, we can safely reset it > + // here since any CPU dereferencing it would only see either the old > + // or the new value (since it is aligned at a natural boundary.) > + // > + mCpuHotEjectData->Handler = NULL; > + return; > + } > + > + // > + // Reached only on APs > + // > + > + // > + // mCpuHotEjectData->QemuSelectorMap[ProcessorNum] is updated > + // on the BSP in the ongoing SMI at two places: > + // > + // - UnplugCpus() where the BSP determines if a CPU is under ejection > + // or not. As a comment in UnplugCpus() at set-up, and in > + // SmmCpuFeaturesRendezvousExit() where it is dereferenced describe, > + // any such updates are guaranteed to be ordered-before the > + // dereference below. > + // > + // - EjectCpu() on the BSP (above) updates QemuSelectorMap[ProcessorNum] > + // for a CPU once it's ejected. > + // > + // The CPU under ejection: might be executing anywhere between the > + // AllCpusInSync loop in SmiRendezvous(), to about to dereference > + // QemuSelectorMap[ProcessorNum]. > + // As described in the comment above where we do the reset, this > + // is not a problem since the ejected CPU never sees the after value. > + // CPUs not-under ejection: never see any changes so they are fine. > + // > QemuSelector = mCpuHotEjectData->QemuSelectorMap[ProcessorNum]; this reference being to the outer one. Thanks Laszlo > if (QemuSelector == CPU_EJECT_QEMU_SELECTOR_INVALID) { > return; > @@ -495,11 +601,6 @@ CpuHotplugMmi ( > if (EFI_ERROR (Status)) { > goto Fatal; > } > - if (ToUnplugCount > 0) { > - DEBUG ((DEBUG_ERROR, "%a: hot-unplug is not supported yet\n", > - __FUNCTION__)); > - goto Fatal; > - } > > if (PluggedCount > 0) { > Status = ProcessHotAddedCpus (mPluggedApicIds, PluggedCount); > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#72870): https://edk2.groups.io/g/devel/message/72870 Mute This Topic: https://groups.io/mt/81273610/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-