]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/MpInitLib: Restore IDT context for APs.
authorEric Dong <eric.dong@intel.com>
Wed, 29 Apr 2020 11:51:20 +0000 (19:51 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 30 Apr 2020 04:11:13 +0000 (04:11 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2683

This patch fixes an assertion because AP can't find the CpuMpData.
When AP is waken up through Init-Sipi-Sipi, AP's IDT should
be restored to pre-allocated buffer so AP can get the CpuMpData
through the IDT base address.
Current code already has logic to handle this when CpuMpData->
InitFlag is ApInitConfig but misses the logic
when CpuMpData->InitFlag is ApInitReconfig.
This patch fixes this gap.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Chandana Kumar <chandana.c.kumar@intel.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
UefiCpuPkg/Library/MpInitLib/MpLib.c

index 64a4c3546e22f254b463a2b4ee279b6e118aba64..ada3969b683c5e5ad5acabe5946d796b16a4d2dd 100644 (file)
@@ -686,18 +686,31 @@ ApWakeupFunction (
         WAKEUP_AP_SIGNAL,\r
         0\r
         );\r
-      if (CpuMpData->ApLoopMode == ApInHltLoop) {\r
-        //\r
-        // Restore AP's volatile registers saved\r
-        //\r
-        RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);\r
-      } else {\r
+\r
+      if (CpuMpData->InitFlag == ApInitReconfig) {\r
         //\r
-        // The CPU driver might not flush TLB for APs on spot after updating\r
-        // page attributes. AP in mwait loop mode needs to take care of it when\r
-        // woken up.\r
+        // ApInitReconfig happens when:\r
+        // 1. AP is re-enabled after it's disabled, in either PEI or DXE phase.\r
+        // 2. AP is initialized in DXE phase.\r
+        // In either case, use the volatile registers value derived from BSP.\r
+        // NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters points to a\r
+        //   different IDT shared by all APs.\r
         //\r
-        CpuFlushTlb ();\r
+        RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);\r
+      }  else {\r
+        if (CpuMpData->ApLoopMode == ApInHltLoop) {\r
+          //\r
+          // Restore AP's volatile registers saved before AP is halted\r
+          //\r
+          RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);\r
+        } else {\r
+          //\r
+          // The CPU driver might not flush TLB for APs on spot after updating\r
+          // page attributes. AP in mwait loop mode needs to take care of it when\r
+          // woken up.\r
+          //\r
+          CpuFlushTlb ();\r
+        }\r
       }\r
 \r
       if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) {\r
@@ -1780,7 +1793,6 @@ MpInitLibInitialize (
       InitializeSpinLock(&CpuMpData->CpuData[Index].ApLock);\r
       CpuMpData->CpuData[Index].CpuHealthy = (CpuInfoInHob[Index].Health == 0)? TRUE:FALSE;\r
       CpuMpData->CpuData[Index].ApFunction = 0;\r
-      CopyMem (&CpuMpData->CpuData[Index].VolatileRegisters, &VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));\r
     }\r
   }\r
 \r