This method may cause SMI storm easily. In case, some processors already entered into SMM but did not set present bit. SMM BSP will send additional SMI to them and bring them into SMM again after they exited from SMM. Then new SMM BSP will send additional SMI to old SMM BSP again.
Jeff -----Original Message----- From: edk2-devel [mailto:[email protected]] On Behalf Of Paolo Bonzini Sent: Monday, October 26, 2015 10:53 AM To: Laszlo Ersek; [email protected] Cc: Kinney, Michael D; Justen, Jordan L Subject: Re: [edk2] [PATCH v3 27/52] OvmfPkg: use relaxed AP SMM synchronization mode On 23/10/2015 17:29, Laszlo Ersek wrote: > I plan to drop this patch, dependent on testing, and on how a new QEMU > patch I've written will be received on qemu-devel. I'm not sure why it can't be fixed within the firmware. Your patch to QEMU to use current_cpu obviously makes sense (that's why it has been merged already :)), but otherwise the firmware should adjust to the hardware, not the other way round. Perhaps we can use a new sync mode (a new PCD would be neater, but you'd have to pass it to BSPHandler and APHandler) to send the IPI from SMM. A simple implementation of the former would be this: diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index dd333a1..1be1a4d 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -377,7 +377,7 @@ !endif !if $(SMM_REQUIRE) == TRUE - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x02 gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|1 !endif diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 9f1ed34..430f1f4 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -383,7 +383,7 @@ [PcdsFixedAtBuild.X64] !if $(SMM_REQUIRE) == TRUE - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x02 gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|2 !endif diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index c0cc92b..b052806 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -382,7 +382,7 @@ !endif !if $(SMM_REQUIRE) == TRUE - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x02 gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|2 !endif diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index b0191cb..7b20e27 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -191,6 +191,29 @@ AllCpusInSmmWithExceptions ( } +VOID +SmmSendSmiToAPs ( + VOID + ) +{ + UINTN Index; + + ASSERT (mSmmMpSyncData->Counter <= mNumberOfCpus); + + if (mSmmMpSyncData->Counter < mNumberOfCpus) { + // + // Send SMI IPIs to bring outside processors in + // + for (Index = mMaxNumberOfCpus; Index-- > 0;) { + if (!mSmmMpSyncData->CpuData[Index].Present && gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) { + SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId); + } + } + } + + return; +} + /** Given timeout constraint, wait for all APs to arrive, and insure when this function returns, no AP will execute normal mode code before entering SMM, except SMI disabled APs. @@ -344,6 +367,16 @@ BSPHandler ( // gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu = CpuIndex; + // + // Manual AP Sync Mode: SmmControl2DxeTrigger only triggers an SMI + // on the processor that executed it, call all other APs. Otherwise + // this is the same as Relaxed mode. + // + if (SyncMode == SmmCpuSyncModeManualAp) { + SmmSendSmiToAPs(); + } + // // If Traditional Sync Mode or need to configure MTRRs: gather all available APs. // @@ -450,12 +482,11 @@ BSPHandler ( ClearSmi(); // - // If Relaxed-AP Sync Mode: gather all available APs after BSP SMM handlers are done, and - // make those APs to exit SMI synchronously. APs which arrive later will be excluded and + // If Relaxed-AP or Manual-AP Sync Mode: gather all available APs + after BSP SMM handlers // are done, and make those APs to exit SMI + synchronously. APs which arrive later will be // will run through freely. // if (SyncMode != SmmCpuSyncModeTradition && !SmmCpuFeaturesNeedConfigureMtrrs()) { - // // Lock the counter down and retrieve the number of APs // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index 71f9b1b..a631811 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -297,6 +297,7 @@ typedef struct { typedef enum { SmmCpuSyncModeTradition, SmmCpuSyncModeRelaxedAp, + SmmCpuSyncModeManualAp, SmmCpuSyncModeMax } SMM_CPU_SYNC_MODE; Paolo _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

