Re: [edk2-devel] [PATCH] Pkg-Module:UefiCpuPkg/MpLib:Do not assume BSP is #0.
Ning, I missed one minor issue with your patch. Can you check if the following GetBspNumber() call can be removed? if (FirstMpHandOff == NULL) { ... } else { ... CpuMpData->CpuCount = MaxLogicalProcessorNumber; CpuMpData->BspNumber = GetBspNumber (FirstMpHandOff); CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; BTW, please remove "Pkg-Module:" from the subject. Thanks, Ray From: Feng, Ning Sent: Friday, May 24, 2024 7:16 To: devel@edk2.groups.io Cc: Feng, Ning ; Ni, Ray Subject: [PATCH] Pkg-Module: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. Cc: Ray Ni Signed-off-by: Ning Feng --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 34 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index d724456502..ae279c6ceb 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -114,6 +114,10 @@ FutureBSPProc ( SaveVolatileRegisters (>APInfo.VolatileRegisters); AsmExchangeRole (>APInfo, >BSPInfo); RestoreVolatileRegisters (>APInfo.VolatileRegisters, FALSE); + // + // Restore VolatileReg saved in CpuMpData->CpuData + // + CopyMem (>CpuData[DataInHob->BspNumber].VolatileRegisters, >APInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS)); } /** @@ -761,11 +765,11 @@ ApWakeupFunction ( 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. - // 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 (>CpuData[0].VolatileRegisters, FALSE); + RestoreVolatileRegisters (>CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack); ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; } else { @@ -798,10 +802,10 @@ ApWakeupFunction ( // 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 +// NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a // different IDT shared by all APs. // -RestoreVolatileRegisters (>CpuData[0].VolatileRegisters, FALSE); +RestoreVolatileRegisters (>CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); } else { if (CpuMpData->ApLoopMode == ApInHltLoop) { // @@ -927,7 +931,7 @@ DxeApEntryPoint ( AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64); } - RestoreVolatileRegisters (>CpuData[0].VolatileRegisters, FALSE); + RestoreVolatileRegisters (>CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); InterlockedIncrement ((UINT32 *)>FinishedCount); PlaceAPInMwaitLoopOrRunLoop ( CpuMpData->ApLoopMode, @@ -2151,7 +2155,12 @@ MpInitLibInitialize ( CpuMpData->BackupBufferSize = ApResetVectorSizeBelow1Mb; CpuMpData->WakeupBuffer = (UINTN)-1; CpuMpData->CpuCount = 1; - CpuMpData->BspNumber= 0; + if (MpHandOff == NULL) { +CpuMpData->BspNumber = 0; + } else { +CpuMpData->BspNumber = GetBspNumber (MpHandOff); + } + CpuMpData->WaitEvent= NULL; CpuMpData->SwitchBspFlag= FALSE; 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. // VolatileRegisters.Tr = 0; - CopyMem (>CpuData[0].VolatileRegisters, , sizeof (VolatileRegisters)); + CopyMem (>CpuData[CpuMpData->BspNumber].VolatileRegisters, , sizeof (VolatileRegisters)); // // 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 // @@ -2615,7 +2624,12 @@ SwitchBSPWorker ( SaveVolatileRegisters (>BSPInfo.VolatileRegisters); AsmExchangeRole (>BSPInfo,
[edk2-devel] [PATCH] Pkg-Module: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. Cc: Ray Ni Signed-off-by: Ning Feng --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 34 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index d724456502..ae279c6ceb 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -114,6 +114,10 @@ FutureBSPProc ( SaveVolatileRegisters (>APInfo.VolatileRegisters); AsmExchangeRole (>APInfo, >BSPInfo); RestoreVolatileRegisters (>APInfo.VolatileRegisters, FALSE); + // + // Restore VolatileReg saved in CpuMpData->CpuData + // + CopyMem (>CpuData[DataInHob->BspNumber].VolatileRegisters, >APInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS)); } /** @@ -761,11 +765,11 @@ ApWakeupFunction ( 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. - // 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 (>CpuData[0].VolatileRegisters, FALSE); + RestoreVolatileRegisters (>CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack); ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; } else { @@ -798,10 +802,10 @@ ApWakeupFunction ( // 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 +// NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a // different IDT shared by all APs. // -RestoreVolatileRegisters (>CpuData[0].VolatileRegisters, FALSE); +RestoreVolatileRegisters (>CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); } else { if (CpuMpData->ApLoopMode == ApInHltLoop) { // @@ -927,7 +931,7 @@ DxeApEntryPoint ( AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64); } - RestoreVolatileRegisters (>CpuData[0].VolatileRegisters, FALSE); + RestoreVolatileRegisters (>CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); InterlockedIncrement ((UINT32 *)>FinishedCount); PlaceAPInMwaitLoopOrRunLoop ( CpuMpData->ApLoopMode, @@ -2151,7 +2155,12 @@ MpInitLibInitialize ( CpuMpData->BackupBufferSize = ApResetVectorSizeBelow1Mb; CpuMpData->WakeupBuffer = (UINTN)-1; CpuMpData->CpuCount = 1; - CpuMpData->BspNumber= 0; + if (MpHandOff == NULL) { +CpuMpData->BspNumber = 0; + } else { +CpuMpData->BspNumber = GetBspNumber (MpHandOff); + } + CpuMpData->WaitEvent= NULL; CpuMpData->SwitchBspFlag= FALSE; 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. // VolatileRegisters.Tr = 0; - CopyMem (>CpuData[0].VolatileRegisters, , sizeof (VolatileRegisters)); + CopyMem (>CpuData[CpuMpData->BspNumber].VolatileRegisters, , sizeof (VolatileRegisters)); // // 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 // @@ -2615,7 +2624,12 @@ SwitchBSPWorker ( SaveVolatileRegisters (>BSPInfo.VolatileRegisters); AsmExchangeRole (>BSPInfo, >APInfo); RestoreVolatileRegisters (>BSPInfo.VolatileRegisters, FALSE); - + // + // Restore VolatileRegs saved in CpuMpData->CpuData + // Don't pass BSP's TR to APs to avoid AP init failure. + // + CopyMem (>CpuData[CpuMpData->NewBspNumber].VolatileRegisters, >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 // -- 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#119161): https://edk2.groups.io/g/devel/message/119161 Mute This Topic: https://groups.io/mt/106263733/21656