summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg
diff options
context:
space:
mode:
authorEric Dong <eric.dong@intel.com>2020-04-29 19:51:20 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-04-30 04:11:13 +0000
commit052aa07da46d96d7069d12f28fc31deb68a6d75e (patch)
tree403400765898f3559d256f4e3c90bac7ce5c6d44 /UefiCpuPkg
parentb2034179e8feed9c7d3bc8f9d40a18fd236c5b57 (diff)
downloadedk2-052aa07da46d96d7069d12f28fc31deb68a6d75e.tar.gz
edk2-052aa07da46d96d7069d12f28fc31deb68a6d75e.tar.bz2
edk2-052aa07da46d96d7069d12f28fc31deb68a6d75e.zip
UefiCpuPkg/MpInitLib: Restore IDT context for APs.
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>
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 64a4c3546e..ada3969b68 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -686,18 +686,31 @@ ApWakeupFunction (
WAKEUP_AP_SIGNAL,
0
);
- if (CpuMpData->ApLoopMode == ApInHltLoop) {
- //
- // Restore AP's volatile registers saved
- //
- RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
- } else {
+
+ if (CpuMpData->InitFlag == ApInitReconfig) {
//
- // The CPU driver might not flush TLB for APs on spot after updating
- // page attributes. AP in mwait loop mode needs to take care of it when
- // woken up.
+ // ApInitReconfig happens when:
+ // 1. AP is re-enabled after it's disabled, in either PEI or DXE phase.
+ // 2. AP is initialized in DXE phase.
+ // In either case, use the volatile registers value derived from BSP.
+ // NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters points to a
+ // different IDT shared by all APs.
//
- CpuFlushTlb ();
+ RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
+ } else {
+ if (CpuMpData->ApLoopMode == ApInHltLoop) {
+ //
+ // Restore AP's volatile registers saved before AP is halted
+ //
+ RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
+ } else {
+ //
+ // The CPU driver might not flush TLB for APs on spot after updating
+ // page attributes. AP in mwait loop mode needs to take care of it when
+ // woken up.
+ //
+ CpuFlushTlb ();
+ }
}
if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) {
@@ -1780,7 +1793,6 @@ MpInitLibInitialize (
InitializeSpinLock(&CpuMpData->CpuData[Index].ApLock);
CpuMpData->CpuData[Index].CpuHealthy = (CpuInfoInHob[Index].Health == 0)? TRUE:FALSE;
CpuMpData->CpuData[Index].ApFunction = 0;
- CopyMem (&CpuMpData->CpuData[Index].VolatileRegisters, &VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
}
}