Paolo,
I do not know if it would help, but there is a hook point already defined in
the SmmCpuFeaturesLib
/**
Processor specific hook point each time a CPU enters System Management Mode.
@param[in] CpuIndex The index of the CPU that has entered SMM. The value
must be between 0 and the NumberOfCpus field in the
System Management System Table (SMST).
**/
VOID
EFIAPI
SmmCpuFeaturesRendezvousEntry (
IN UINTN CpuIndex
);
In the OVMF specific implementation of this lib, you can do special actions if
CpuIndex is BSP, for example check to see if it is a SW SMI and send IPI to APs.
I also see that Jeff Fan has responded to the thread and is working on making
sure the APs are in a good state between ExitBootServices() and OS wake of APs.
Best regards,
Mike
>-----Original Message-----
>From: Paolo Bonzini [mailto:[email protected]] On Behalf Of Paolo
>Bonzini
>Sent: Sunday, October 25, 2015 7:53 PM
>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