mirror of https://review.coreboot.org/STM.git
Start VM/PE frpm non-VM/PE processor
Current implementation of STM/PE requires that the VM/PE and any run commands that affect the VM/PE be done on the VM/PE processor. On most operating systems, the VM/PE processor has been hot unplugged from the available processor set. Getting commands to the VM/PE requires some modification of the operating system for this action to be supported and this implemantation is fragile across releases. This patch allows VM/PE commands to issued via a vmcall on any processor. The STM will setup a SMI timer interrupt to cause the command to be passed to the VM/PE processor. This greatly reduces and simplifies the changes needed for the O/S. Signed-off-by: Eugene Myers <edmyers@cyberpackventures.com>
This commit is contained in:
parent
449be74faf
commit
fa187042a9
|
@ -34,16 +34,16 @@ extern UINT32 GetMPState;
|
|||
static int CpuGetState = 0;
|
||||
|
||||
void SetEndOfSmi(void);
|
||||
void StartTimer(void);
|
||||
void StartPeriodicTimer(void);
|
||||
void StopTimer(void);
|
||||
void ClearTimerSTS(void);
|
||||
void SetMaxSwTimerInt(void);
|
||||
void SetMinSwTimerInt(void);
|
||||
void SetTimerRate(UINT16 value);
|
||||
void SetPeriodicTimerRate(UINT16 value);
|
||||
|
||||
extern void MapVmcs();
|
||||
void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex);
|
||||
void AckTimer(void);
|
||||
void AckPeriodicTimer(void);
|
||||
UINT16 get_pmbase(void);
|
||||
|
||||
UINT32 save_Inter_PeVm(UINT32 CpuIndex);
|
||||
|
@ -130,7 +130,7 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
if(0 >= EndSize)
|
||||
{
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld LaunchPeVM - VM/PE heap space not cleared because of DoNotClearSize too large\n",
|
||||
"%ld LaunchPeVm - VM/PE heap space not cleared because of DoNotClearSize too large\n",
|
||||
CpuIndex));
|
||||
}
|
||||
else
|
||||
|
@ -171,7 +171,7 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
// save the state, process the SMI, then start the VM/PE afterwards
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVM - SMI being processed - faking NMI - PeSmiState: %ld\n",
|
||||
"%ld LaunchPeVm - SMI being processed - faking NMI - PeSmiState: %ld\n",
|
||||
CpuIndex,
|
||||
PeSmiControl.PeSmiState));
|
||||
}
|
||||
|
@ -219,14 +219,15 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
SHARED_PAGE_STM_HEADER * SharedPageStmHeader = (SHARED_PAGE_STM_HEADER *) (UINT64*) PeVmData[PeType].SharedPageStm;
|
||||
SharedPageStmHeader->RunCount = PeVmData[PeType].UserModule.RunCount;
|
||||
SharedPageStmHeader->ExecProcessor = CpuIndex;
|
||||
SharedPageStmHeader->NumProcessors = mHostContextCommon.CpuNum;
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVM - Initiating PE/VM run number: %d\n",
|
||||
"%ld LaunchPeVm - Initiating PE/VM run number: %d\n",
|
||||
CpuIndex,
|
||||
PeVmData[PeType].UserModule.RunCount));
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVM - SharedPageStm 0x%016llx 0x%016llx 0x%016llx\n",
|
||||
"%ld LaunchPeVm - SharedPageStm NumProcessors: %d RunCount: %d ExecProc: %d\n",
|
||||
CpuIndex,
|
||||
SharedPageStmHeader->NumProcessors,
|
||||
SharedPageStmHeader->RunCount,
|
||||
|
@ -264,11 +265,11 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
// which will cause the SMI for this processor to be fired
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVM - SMI detected during build - delaying launch to handle SMI\n",
|
||||
"%ld LaunchPeVm - SMI detected during build - delaying launch to handle SMI\n",
|
||||
CpuIndex));
|
||||
save_Inter_PeVm(CpuIndex);
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld LaunchPeVM - Warning: Return from non-returnable function\n",
|
||||
"%ld LaunchPeVm - Warning: Return from non-returnable function\n",
|
||||
CpuIndex));
|
||||
}
|
||||
|
||||
|
@ -277,7 +278,7 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
if(NMIReceived > 1)
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVM - NMI detected during build - delaying launch to handle SMI\n",
|
||||
"%ld LaunchPeVm - NMI detected during build - delaying launch to handle SMI\n",
|
||||
CpuIndex));
|
||||
|
||||
// This will cause the current PE/VM state to be saved and fake a return to the MLE
|
||||
|
@ -286,13 +287,13 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
|
||||
save_Inter_PeVm(CpuIndex);
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld LaunchPeVM - Warning: Return from non-returnable function\n",
|
||||
"%ld LaunchPeVm - Warning: Return from non-returnable function\n",
|
||||
CpuIndex));
|
||||
// this function should not return
|
||||
}
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVM - Launching PE/VM - NMIReceived: %d\n",
|
||||
"%ld LaunchPeVm - Launching PE/VM - NMIReceived: %d\n",
|
||||
CpuIndex,
|
||||
NMIReceived));
|
||||
|
||||
|
@ -302,7 +303,7 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
"%ld LaunchPeVm - !!!LaunchGuestSmm fail for PeVm!!!\n",
|
||||
CpuIndex));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld LaunchPeVm - Rflags: (UINTN)CpuIndex, %08llx\n",
|
||||
"%ld LaunchPeVm - Rflags: %08llx\n",
|
||||
CpuIndex,
|
||||
Rflags));
|
||||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n",
|
||||
|
@ -340,6 +341,7 @@ STM_STATUS RunPermVM(UINT32 CpuIndex)
|
|||
{
|
||||
UINT32 rc;
|
||||
UINT32 PeType = PE_PERM; // can only restart perm vms...
|
||||
UINT32 SetupMode = RESTART_VM;
|
||||
|
||||
// (for now) start the VM...
|
||||
|
||||
|
@ -371,6 +373,8 @@ STM_STATUS RunPermVM(UINT32 CpuIndex)
|
|||
}
|
||||
return rc;
|
||||
}
|
||||
else if(PeVmData[PeType].PeVmState == PE_VM_WAIT_START)
|
||||
SetupMode = NEW_VM;
|
||||
|
||||
PeVmData[PeType].PeVmState = PE_VM_ACTIVE;
|
||||
|
||||
|
@ -387,7 +391,7 @@ STM_STATUS RunPermVM(UINT32 CpuIndex)
|
|||
|
||||
rc = SetupProtExecVm(CpuIndex,
|
||||
PeVmData[PE_PERM].UserModule.VmConfig,
|
||||
RESTART_VM,
|
||||
SetupMode,
|
||||
PeType); // can only restart PERM_VM
|
||||
|
||||
if(rc != PE_SUCCESS) // did we have a problem
|
||||
|
@ -401,6 +405,8 @@ STM_STATUS RunPermVM(UINT32 CpuIndex)
|
|||
|
||||
LaunchPeVm(PeType, CpuIndex); // Launch the PE/VM
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld - Error in launching PE VM\n", CpuIndex));
|
||||
|
||||
PeVmData[PE_PERM].PeVmState = PE_VM_AVAIL; // not there anymore
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType = SMI_HANDLER;
|
||||
return rc;
|
||||
|
@ -526,10 +532,10 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
|
||||
// turn on the timer
|
||||
|
||||
SetTimerRate(PeriodicSmi16Sec);
|
||||
StartTimer();
|
||||
SetPeriodicTimerRate(PeriodicSmi16Sec);
|
||||
StartPeriodicTimer();
|
||||
|
||||
AckTimer();
|
||||
AckPeriodicTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#include "StmRuntime.h"
|
||||
#include "PeStm.h"
|
||||
|
||||
void SetTimerRate(UINT16 value);
|
||||
void SetPeriodicTimerRate(UINT16 value);
|
||||
|
||||
// interval timer support
|
||||
|
||||
|
@ -132,23 +132,33 @@ UINT16 get_pmbase(void)
|
|||
return pmbase;
|
||||
}
|
||||
|
||||
void StartTimer(void)
|
||||
void StartTimer(UINT32 enable, UINT32 status)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
UINT32 smi_sts = IoRead32(pmbase + SMI_STS);
|
||||
|
||||
smi_en |= PERIODIC_EN;
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
"StartTimer - smi_en: 0x%08lx smi_sts: 0x%08lx\n",
|
||||
smi_en,
|
||||
smi_sts));
|
||||
#endif
|
||||
IoWrite32(pmbase + SMI_STS, PERIODIC_STS);
|
||||
smi_en |= enable;
|
||||
IoWrite32(pmbase + SMI_STS, status);
|
||||
IoWrite32(pmbase + SMI_EN, smi_en);
|
||||
}
|
||||
|
||||
void StartPeriodicTimer(void)
|
||||
{
|
||||
StartTimer(PERIODIC_EN, PERIODIC_STS);
|
||||
}
|
||||
|
||||
void StartSwSmiTimer(void)
|
||||
{
|
||||
StartTimer(SWSMI_TMR_EN, SWSMI_TMR_STS);
|
||||
}
|
||||
|
||||
void SetEndOfSmi(void)
|
||||
{
|
||||
|
||||
|
@ -180,7 +190,7 @@ void PrintSmiEnRegister(UINT32 Index)
|
|||
IoRead32(pmbase + SMI_STS)));
|
||||
}
|
||||
|
||||
void AckTimer(void)
|
||||
void AckPeriodicTimer(void)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
|
||||
|
@ -193,15 +203,25 @@ void AckTimer(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
void StopSwTimer(void)
|
||||
void StopTimer(UINT32 enable)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
|
||||
smi_en &= ~PERIODIC_EN;
|
||||
smi_en &= ~enable;
|
||||
IoWrite32(pmbase + SMI_EN, smi_en);
|
||||
}
|
||||
|
||||
void StopPeriodicTimer(void)
|
||||
{
|
||||
StopTimer(PERIODIC_EN);
|
||||
}
|
||||
|
||||
void StopSwSmiTimer(void)
|
||||
{
|
||||
StopTimer(SWSMI_TMR_EN);
|
||||
}
|
||||
|
||||
/*
|
||||
* CheckTimerSTS
|
||||
* Input:
|
||||
|
@ -217,18 +237,23 @@ int CheckTimerSTS(UINT32 Index)
|
|||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_sts = IoRead32(pmbase + SMI_STS);
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
|
||||
// only care about the ones that are enabled
|
||||
|
||||
smi_sts = smi_en & smi_sts;
|
||||
|
||||
#if 0
|
||||
DEBUG((EFI_D_ERROR, "%ld CheckTimerSTS - 0x%08lx\n", Index, smi_sts));
|
||||
#endif
|
||||
if((smi_sts & PERIODIC_STS) == PERIODIC_STS)
|
||||
{
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
UINT32 other_smi = (smi_en & smi_sts) & ~PERIODIC_STS;
|
||||
UINT32 other_smi = smi_sts & ~PERIODIC_STS;
|
||||
|
||||
if(other_smi == 0)
|
||||
{
|
||||
if(other_smi == 0)
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - Timer Interrupt Detected\n",
|
||||
"%ld CheckTimerSTS - Periodic Timer SMI\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
return 1;
|
||||
|
@ -236,14 +261,36 @@ int CheckTimerSTS(UINT32 Index)
|
|||
else
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - Timer + other SMI found\n",
|
||||
"%ld CheckTimerSTS - Periodic Timer + other SMI\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
if((smi_sts & SWSMI_TMR_STS) == SWSMI_TMR_STS)
|
||||
{
|
||||
UINT32 other_smi = smi_sts & ~SWSMI_TMR_STS;
|
||||
StopSwSmiTimer();
|
||||
|
||||
if(other_smi == 0)
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - SWSMI\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - SWSMI + other SMI found\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - No Timer Interrupt Detected\n",
|
||||
|
@ -251,10 +298,9 @@ int CheckTimerSTS(UINT32 Index)
|
|||
smi_sts));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ClearTimerSTS()
|
||||
void ClearPeriodicTimerSTS()
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
|
||||
|
@ -262,17 +308,17 @@ void ClearTimerSTS()
|
|||
IoWrite32(pmbase + SMI_STS, PERIODIC_STS);
|
||||
}
|
||||
|
||||
void SetMaxSwTimerInt()
|
||||
void SetMaxPeriodicTimerInt()
|
||||
{
|
||||
SetTimerRate(3);
|
||||
SetPeriodicTimerRate(3);
|
||||
}
|
||||
|
||||
void SetMinSwTimerInt()
|
||||
void SetMinPeriodicTimerInt()
|
||||
{
|
||||
SetTimerRate(0);
|
||||
SetPeriodicTimerRate(0);
|
||||
}
|
||||
|
||||
void SetTimerRate(UINT16 value)
|
||||
void SetPeriodicTimerRate(UINT16 value)
|
||||
{
|
||||
UINT16 Reg16;
|
||||
UINT16 TimeOut;
|
||||
|
@ -287,3 +333,19 @@ void SetTimerRate(UINT16 value)
|
|||
Reg16 = pcie_read_config16(PcuDev, D31F0_GEN_PMCON_1);
|
||||
pcie_write_config16(PcuDev, D31F0_GEN_PMCON_1, Reg16|TimeOut);
|
||||
}
|
||||
|
||||
void SetSwSmiTimerRate(UINT16 value)
|
||||
{
|
||||
UINT16 Reg16;
|
||||
UINT16 TimeOut;
|
||||
device_t PcuDev = get_pcu_dev();
|
||||
|
||||
if( value > 3)
|
||||
{
|
||||
value = 3;
|
||||
}
|
||||
TimeOut = (value << 6);
|
||||
|
||||
Reg16 = pcie_read_config16(PcuDev, D31F0_GEN_PMCON_3);
|
||||
pcie_write_config16(PcuDev, D31F0_GEN_PMCON_3, Reg16|TimeOut);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ extern int CheckAndGetState(UINT32 CpuIndex);
|
|||
extern void CpuReadySync(UINT32 Index);
|
||||
extern PE_VM_DATA PeVmData[4]; // right now support a max of 3 PE VM (VM 0 is the SMI_HANDLER)
|
||||
extern int CheckTimerSTS(UINT32 Index);
|
||||
extern void StopSwTimer(void);
|
||||
extern void StopPeriodicTimer(void);
|
||||
extern void SetEndOfSmi(void);
|
||||
extern void PrintVmxState(UINT32 CpuIndex, ROOT_VMX_STATE * RootState);
|
||||
|
||||
|
@ -130,7 +130,7 @@ UINT32 PeSmiHandler(UINT32 CpuIndex)
|
|||
if (PeSmiControl.PeCpuIndex == (INT32)CpuIndex)
|
||||
{
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeWaitTimer, 1, 0);
|
||||
StopSwTimer();
|
||||
StopPeriodicTimer();
|
||||
|
||||
// start the VM/PE
|
||||
PeVmData[PeType].StartMode = PEVM_PRESTART_SMI; // starting from SMI
|
||||
|
|
|
@ -10,6 +10,8 @@ extern void print_region_list(UINT32 PeType, UINT32 CpuIndex);
|
|||
extern UINT32 SetupProtExecVm(UINT32 CpuIndex, UINT32 VM_Configuration, UINT32 mode, UINT32 PeType);
|
||||
extern void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex);
|
||||
extern VOID EptDumpPageTable (IN EPT_POINTER *EptPointer );
|
||||
extern void SetSwSmiTimerRate(UINT16 value);
|
||||
extern void StartSwSmiTimer(void);
|
||||
static UINT32 setupModulepages(UINT32 PeType, UINT32 CpuIndex);
|
||||
|
||||
STM_STATUS AddPeVm(UINT32 CpuIndex, PE_MODULE_INFO * callerDataStructure, UINT32 PeType, UINT32 RunVm)
|
||||
|
@ -78,6 +80,13 @@ STM_STATUS AddPeVm(UINT32 CpuIndex, PE_MODULE_INFO * callerDataStructure, UINT32
|
|||
PeVmData[PeType].UserModule.DoNotClearSize = callerDataStructure->DoNotClearSize;
|
||||
PeVmData[PeType].UserModule.RunCount = 0;
|
||||
|
||||
if(callerDataStructure->Processor < mHostContextCommon.CpuNum)
|
||||
PeVmData[PeType].UserModule.Processor = callerDataStructure->Processor;
|
||||
else
|
||||
PeVmData[PeType].UserModule.Processor = 0;
|
||||
|
||||
PeVmData[PeType].UserModule.LastRunStatus = 0;
|
||||
|
||||
#if defined (MDE_CPU_X64)
|
||||
sourceBuffer = (UINTN *)((PeVmData[PeType].UserModule.ModuleAddress));
|
||||
#else
|
||||
|
@ -163,6 +172,17 @@ STM_STATUS AddPeVm(UINT32 CpuIndex, PE_MODULE_INFO * callerDataStructure, UINT32
|
|||
// calculate the location within the allocated space to place the module
|
||||
destBuffer = PeVmData[PeType].SmmBuffer + PeVmData[PeType].UserModule.AddressSpaceStart -
|
||||
PeVmData[PeType].UserModule.ModuleLoadAddress;
|
||||
|
||||
// sanity check - make sure the module lands in the allocated buffer
|
||||
|
||||
if( (destBuffer < PeVmData[PeType].SmmBuffer) ||
|
||||
(destBuffer + PeVmData[PeType].UserModule.ModuleSize >
|
||||
PeVmData[PeType].SmmBuffer + (numModulePages << 12)))
|
||||
{
|
||||
FreePE_DataStructures(PeType);
|
||||
PeVmData[PeType].PeVmState = PE_VM_AVAIL;
|
||||
return(PE_MODULE_TOO_LARGE);
|
||||
}
|
||||
}
|
||||
|
||||
// make sure that the size of the module will fit into the allocated space
|
||||
|
@ -390,36 +410,55 @@ STM_STATUS AddPeVm(UINT32 CpuIndex, PE_MODULE_INFO * callerDataStructure, UINT32
|
|||
// (for now) start the VM...
|
||||
PeVmData[PeType].StartMode = PEVM_START_VMCALL;
|
||||
|
||||
rc = SetupProtExecVm(CpuIndex, PeVmData[PeType].UserModule.VmConfig, NEW_VM, PeType);
|
||||
|
||||
if(rc != PE_SUCCESS) // did we have a problem
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld AddPeVm - Error in configuring PE VM\n", CpuIndex));
|
||||
FreePE_DataStructures(PeType);
|
||||
//setPEerrorCode(rc, StmVmm); // tell the caller of the problem
|
||||
PeVmData[PeType].PeVmState = PE_VM_AVAIL; // not there anymore
|
||||
// StmVmm->NonSmiHandler = 0; // no longer an PE VM
|
||||
AsmVmPtrLoad(&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Vmcs);
|
||||
|
||||
/// at this point we should return to the MLE as per the Intel method...
|
||||
|
||||
AsmVmClear(&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Vmcs);
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType = SMI_HANDLER;
|
||||
return(rc);
|
||||
}
|
||||
DEBUG((EFI_D_ERROR, "%ld AddPeVm - sucessfully completed - PeApicId: 0x%llx PeType: %d\n", CpuIndex, PeSmiControl.PeApicId, PeType));
|
||||
DEBUG((EFI_D_ERROR, "%ld AddPeVm - sucessfully completed - PeApicId: 0x%llx PeType: %d\n",
|
||||
CpuIndex, PeSmiControl.PeApicId, PeType));
|
||||
|
||||
if(RunVm == 1)
|
||||
{
|
||||
PeVmData[PeType].StartMode = PEVM_START_VMCALL;
|
||||
LaunchPeVm(PeType, CpuIndex); // launch the PE/VM
|
||||
if((PeVmData[PeType].UserModule.Processor == 0) ||
|
||||
(PeVmData[PeType].UserModule.Processor == CpuIndex))
|
||||
{
|
||||
//Execution is only on this processor
|
||||
rc = SetupProtExecVm(CpuIndex, PeVmData[PeType].UserModule.VmConfig, NEW_VM, PeType);
|
||||
|
||||
// if we get to this point the PeVm has failed to launch so we need clean up the mess
|
||||
// and return the error to the caller
|
||||
FreePE_DataStructures(PeType);
|
||||
DEBUG((EFI_D_ERROR, "%ld AddPeVm - VM/PE Launch Failure\n", CpuIndex));
|
||||
rc = PE_VMLAUNCH_ERROR;
|
||||
PeVmData[PeType].PeVmState = PE_VM_AVAIL; // not there anymore
|
||||
if(rc != PE_SUCCESS) // did we have a problem
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld AddPeVm - Error in configuring PE VM\n", CpuIndex));
|
||||
FreePE_DataStructures(PeType);
|
||||
PeVmData[PeType].PeVmState = PE_VM_AVAIL; // not there anymore
|
||||
AsmVmPtrLoad(&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Vmcs);
|
||||
AsmVmClear(&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Vmcs);
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType = SMI_HANDLER;
|
||||
return(rc);
|
||||
}
|
||||
PeVmData[PeType].StartMode = PEVM_START_VMCALL;
|
||||
LaunchPeVm(PeType, CpuIndex); // launch the PE/VM
|
||||
|
||||
// if we get to this point the PeVm has failed to launch so
|
||||
// we need to clean up and return the error to the caller
|
||||
FreePE_DataStructures(PeType);
|
||||
DEBUG((EFI_D_ERROR, "%ld AddPeVm - VM/PE Launch Failure\n", CpuIndex));
|
||||
rc = PE_VMLAUNCH_ERROR;
|
||||
PeVmData[PeType].PeVmState = PE_VM_AVAIL; // not there anymore
|
||||
}
|
||||
else
|
||||
{
|
||||
// execution will not be on this processor, setup to get it
|
||||
// to where it belongs
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld AddPeVM - Execution is to be on processor %ld\n",
|
||||
CpuIndex, PeVmData[PeType].UserModule.Processor));
|
||||
|
||||
PeSmiControl.PeCpuIndex = PeVmData[PeType].UserModule.Processor;
|
||||
mHostContextCommon.HostContextPerCpu[PeSmiControl.PeCpuIndex].NonSmiHandler = PeType;
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeWaitTimer, 0, 1);
|
||||
PeVmData[PeType].PeVmState = PE_VM_WAIT_START;
|
||||
PeVmData[PeType].StartMode = PEVM_PRESTART_SMI;
|
||||
SetSwSmiTimerRate(0); // 1.5ms
|
||||
StartSwSmiTimer();
|
||||
AsmWbinvd();
|
||||
rc = STM_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -43,18 +43,21 @@ typedef struct
|
|||
UINT64 AddressSpaceStart; // start of guest physical address space (page aligned)
|
||||
UINT32 AddressSpaceSize; // size of guest physical address space
|
||||
UINT32 VmConfig; // Options to the configuration of the PE/VM
|
||||
UINT64 Cr3Load; // CR3
|
||||
UINT64 SharedPage; // writeable pages for sharing between the PE Module and kernel space
|
||||
// can be multible pages and is located in mail memory
|
||||
UINT64 Cr3Load; // CR3
|
||||
UINT64 SharedPage; // writeable pages for sharing between the PE Module and kernel space
|
||||
// can be multible pages and is located in mail memory
|
||||
PE_REGION_LIST *Segment; // list of read only regions (contained within a page)
|
||||
UINT32 SharedPageSize; // size of]SharedPage/region
|
||||
UINT32 DoNotClearSize; // area at beginning of memory not to be cleared
|
||||
UINT64 ModuleDataSection; // Location of Module Data Section for VM/PE
|
||||
UINT32 Processor; // assigned processor (0 = use current processor)
|
||||
UINT32 reserved;
|
||||
|
||||
// data areas local to the STM go after this point
|
||||
|
||||
UINT64 SharedStmPage; // page shared between PE/VM and the STM
|
||||
UINT64 RunCount; // count of runs starting with one (1)
|
||||
UINT64 LastRunStatus; // Status of last VM/PE run
|
||||
// UINTN DataRegionStart; // data space after text region
|
||||
UINTN DataRegionSize; // data space size
|
||||
UINTN FrontDataRegionSize; // data space size before text region
|
||||
|
|
Loading…
Reference in New Issue