UefiCpuPkg/MpLib:Do not assume BSP is #0.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4778

MPInitlib have wrong expectation that BSP index should always be 0 in
MpInitLibInitialize(), SwitchBsp(),ApWakeupFunction().
That will cause the data mismatch, if the initial BSP is not 0.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Ning Feng <ning.feng@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
This commit is contained in:
Ning Feng 2024-05-23 06:01:14 -04:00 committed by Liming Gao
parent 3e722403cd
commit 88a4de450f

View File

@ -1,7 +1,7 @@
/** @file /** @file
CPU MP Initialize Library common functions. CPU MP Initialize Library common functions.
Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR> Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR> Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@ -114,6 +114,10 @@ FutureBSPProc (
SaveVolatileRegisters (&DataInHob->APInfo.VolatileRegisters); SaveVolatileRegisters (&DataInHob->APInfo.VolatileRegisters);
AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo); AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo);
RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, FALSE); RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, FALSE);
//
// Update VolatileRegisters saved in CpuMpData->CpuData
//
CopyMem (&DataInHob->CpuData[DataInHob->BspNumber].VolatileRegisters, &DataInHob->APInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
} }
/** /**
@ -761,11 +765,11 @@ ApWakeupFunction (
BistData = (UINT32)ApStackData->Bist; BistData = (UINT32)ApStackData->Bist;
// //
// CpuMpData->CpuData[0].VolatileRegisters is initialized based on BSP environment, // CpuMpData->CpuData[BspNumber].VolatileRegisters is initialized based on BSP environment,
// to initialize AP in InitConfig path. // to initialize AP in InitConfig path.
// NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters points to a different IDT shared by all APs. // NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a different IDT shared by all APs.
// //
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE); RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack); InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack);
ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
} else { } else {
@ -798,10 +802,10 @@ ApWakeupFunction (
// 1. AP is re-enabled after it's disabled, in either PEI or DXE phase. // 1. AP is re-enabled after it's disabled, in either PEI or DXE phase.
// 2. AP is initialized in DXE phase. // 2. AP is initialized in DXE phase.
// In either case, use the volatile registers value derived from BSP. // In either case, use the volatile registers value derived from BSP.
// NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters points to a // NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a
// different IDT shared by all APs. // different IDT shared by all APs.
// //
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE); RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
} else { } else {
if (CpuMpData->ApLoopMode == ApInHltLoop) { if (CpuMpData->ApLoopMode == ApInHltLoop) {
// //
@ -927,7 +931,7 @@ DxeApEntryPoint (
AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64); AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64);
} }
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE); RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount); InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount);
PlaceAPInMwaitLoopOrRunLoop ( PlaceAPInMwaitLoopOrRunLoop (
CpuMpData->ApLoopMode, CpuMpData->ApLoopMode,
@ -2151,7 +2155,12 @@ MpInitLibInitialize (
CpuMpData->BackupBufferSize = ApResetVectorSizeBelow1Mb; CpuMpData->BackupBufferSize = ApResetVectorSizeBelow1Mb;
CpuMpData->WakeupBuffer = (UINTN)-1; CpuMpData->WakeupBuffer = (UINTN)-1;
CpuMpData->CpuCount = 1; CpuMpData->CpuCount = 1;
if (FirstMpHandOff == NULL) {
CpuMpData->BspNumber = 0; CpuMpData->BspNumber = 0;
} else {
CpuMpData->BspNumber = GetBspNumber (FirstMpHandOff);
}
CpuMpData->WaitEvent = NULL; CpuMpData->WaitEvent = NULL;
CpuMpData->SwitchBspFlag = FALSE; CpuMpData->SwitchBspFlag = FALSE;
CpuMpData->CpuData = (CPU_AP_DATA *)(CpuMpData + 1); CpuMpData->CpuData = (CPU_AP_DATA *)(CpuMpData + 1);
@ -2186,11 +2195,11 @@ MpInitLibInitialize (
// Don't pass BSP's TR to APs to avoid AP init failure. // Don't pass BSP's TR to APs to avoid AP init failure.
// //
VolatileRegisters.Tr = 0; VolatileRegisters.Tr = 0;
CopyMem (&CpuMpData->CpuData[0].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters)); CopyMem (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));
// //
// Set BSP basic information // Set BSP basic information
// //
InitializeApData (CpuMpData, 0, 0, CpuMpData->Buffer + ApStackSize); InitializeApData (CpuMpData, CpuMpData->BspNumber, 0, CpuMpData->Buffer + ApStackSize * (CpuMpData->BspNumber + 1));
// //
// Save assembly code information // Save assembly code information
// //
@ -2246,7 +2255,6 @@ MpInitLibInitialize (
} }
CpuMpData->CpuCount = MaxLogicalProcessorNumber; CpuMpData->CpuCount = MaxLogicalProcessorNumber;
CpuMpData->BspNumber = GetBspNumber (FirstMpHandOff);
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
for (MpHandOff = FirstMpHandOff; for (MpHandOff = FirstMpHandOff;
MpHandOff != NULL; MpHandOff != NULL;
@ -2615,7 +2623,12 @@ SwitchBSPWorker (
SaveVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters); SaveVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters);
AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo); AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo);
RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, FALSE); RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, FALSE);
//
// Update VolatileRegisters saved in CpuMpData->CpuData
// Don't pass BSP's TR to APs to avoid AP init failure.
//
CopyMem (&CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters, &CpuMpData->BSPInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters.Tr = 0;
// //
// Set the BSP bit of MSR_IA32_APIC_BASE on new BSP // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
// //