]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
OvmfPkg/SmmCpuFeaturesLib: call CPU hot-eject handler
[mirror_edk2.git] / OvmfPkg / Library / SmmCpuFeaturesLib / SmmCpuFeaturesLib.c
index 5c025bc717c33f89f05ed420498bdfe4c2ebc928..fdf2380974fa20c1b24cb37267514bf99de15aaa 100644 (file)
@@ -452,6 +452,40 @@ SmmCpuFeaturesRendezvousExit (
   IN UINTN  CpuIndex\r
   )\r
 {\r
+  //\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
 }\r
 \r
 /**\r