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>
This commit is contained in:
Eric Dong 2020-04-29 19:51:20 +08:00 committed by mergify[bot]
parent b2034179e8
commit 052aa07da4
1 changed files with 23 additions and 11 deletions

View File

@ -686,18 +686,31 @@ ApWakeupFunction (
WAKEUP_AP_SIGNAL, WAKEUP_AP_SIGNAL,
0 0
); );
if (CpuMpData->ApLoopMode == ApInHltLoop) {
if (CpuMpData->InitFlag == ApInitReconfig) {
// //
// Restore AP's volatile registers saved // 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.
// //
RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE); RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
} else { } else {
// if (CpuMpData->ApLoopMode == ApInHltLoop) {
// 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 // Restore AP's volatile registers saved before AP is halted
// woken up. //
// RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
CpuFlushTlb (); } 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) { if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) {
@ -1780,7 +1793,6 @@ MpInitLibInitialize (
InitializeSpinLock(&CpuMpData->CpuData[Index].ApLock); InitializeSpinLock(&CpuMpData->CpuData[Index].ApLock);
CpuMpData->CpuData[Index].CpuHealthy = (CpuInfoInHob[Index].Health == 0)? TRUE:FALSE; CpuMpData->CpuData[Index].CpuHealthy = (CpuInfoInHob[Index].Health == 0)? TRUE:FALSE;
CpuMpData->CpuData[Index].ApFunction = 0; CpuMpData->CpuData[Index].ApFunction = 0;
CopyMem (&CpuMpData->CpuData[Index].VolatileRegisters, &VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
} }
} }