Fix some concurrency problems with SMI handling while a VM/PE is being launched

This commit is contained in:
Eugene Myers 2018-11-08 11:41:57 -05:00
parent a1346f9c73
commit 3feb15e43e
7 changed files with 18 additions and 16 deletions

View File

@ -384,6 +384,7 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
// indicate that we are not running
PeSmiControl.PeExec = 0;
// bug - think about this one....
PeSmiControl.PeSmiState = PESMINULL; // indicate that we are out of it
if(mode == PRESERVE_VM)
@ -660,7 +661,7 @@ UINT32 RestoreInterPeVm(UINT32 CpuIndex, UINT32 PeType)
}
}
if(PeSmiControl.PeSmiState == PESMIHSMI)
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMIHSMI) == PESMIHSMI)
{
DEBUG((EFI_D_ERROR, "%ld RestoreInterPeVm - SMI in progress - aborting PE/VM restart\n", CpuIndex));
return 1;

View File

@ -30,25 +30,24 @@ UINT32 PeSmiHandler(UINT32 CpuIndex)
UINT32 PeType = PE_PERM;
UINT32 CpuNum;
if(CpuIndex == 0)
{
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMINULL, PESMIHSMI);
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMINULL, PESMIHSMI);
//DEBUG((EFI_D_ERROR, "%ld PeSmiHandler - CurrPeSmiState %ld\n", CpuIndex, PeSmiControl.PeSmiState));
}
if(PeSmiControl.PeCpuIndex == (INT32)CpuIndex )
if(PeSmiControl.PeCpuIndex == (INT32)CpuIndex ) // when the pe/vm comes in...
{
//DEBUG((EFI_D_ERROR, "%ld PeSmiHandler - VM/PE responded to SMI, CurrPeSmiState %ld\n", CpuIndex, PeSmiControl.PeSmiState));
//DEBUG((EFI_D_ERROR, "%ld PeSmiHandler - VM/PE responded to SMI, CurrPeSmiState %ld\n", CpuIndex, PeSmiControl.PeSmiState));
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIPNMI2, PESMINULL);
}
if(PESMIPNMI == PeSmiControl.PeSmiState)
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIPNMI, PESMIPNMI2) == PESMIPNMI)
///PESMIPNMI == PeSmiControl.PeSmiState)
{
// eventually the VM/PE will be started (or at least built) and this will cause one of the processors
// to send a NMI to the VM/PE processor causing it to drop out and process the SMI
// when it does, all processors will exit this loop and process the SMI as usual
SignalPeVm(CpuIndex); // make sure that the PE/VM processes this SMI as well
PeSmiControl.PeSmiState = PESMINULL;
//PeSmiControl.PeSmiState = PESMINULL;
}
@ -148,8 +147,8 @@ UINT32 PeSmiHandler(UINT32 CpuIndex)
{
if(CpuIndex == 0)
{
PeSmiControl.PeSmiState = PESMINULL;
//InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMINULL); // one of these will work
//PeSmiControl.PeSmiState = PESMINULL;
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMINULL); // one of these will work
}
retvalue = 0;
}

View File

@ -4,11 +4,12 @@
// VM/PE PeSmiControl.PeSmiState state definitions
#define PESMINULL 0 // nothing happening
#define PESMIPSMI 1 // SMI sent by VM/PE startup to get cpu state
#define PESMIHSMI 2 // normal SMI processing
#define PESMIPNMI 3 // VM/PE needs an NMI sent for it to help process the host SMI
#define PESMIHTMR 4 // smi handler has detected an SMI timer
#define PESMINULL 0 // nothing happening
#define PESMIPSMI 1 // SMI sent by VM/PE startup to get cpu state
#define PESMIHSMI 2 // normal SMI processing
#define PESMIPNMI 3 // VM/PE needs an NMI sent for it to help process the host SMI
#define PESMIHTMR 4 // smi handler has detected an SMI timer
#define PESMIPNMI2 5 // NMI has been sent to the VM/PE, now waiting for its entry
#define OFFSET_BITMASK_IA32_4K 0x00000FFF
#define OFFSET_BITMASK_IA32E_4K 0x0000000000000FFF

View File

@ -9,6 +9,7 @@
#define PESMIHSMI 2 // normal SMI processing
#define PESMIPNMI 3 // VM/PE needs an NMI sent for it to help process the host SMI
#define PESMIHTMR 4 // smi handler has detected an SMI timer
#define PESMIPNMI2 5 // nmi has been sent to VM/PE - waiting for response
#define OFFSET_BITMASK_IA32_4K 0x00000FFF
#define OFFSET_BITMASK_IA32E_4K 0x0000000000000FFF