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