mirror of https://review.coreboot.org/STM.git
Code cleanup - PeLoadVm.c
This commit is contained in:
parent
71f2de651d
commit
50475a6f18
|
@ -36,7 +36,6 @@ static int CpuGetState = 0;
|
|||
void SetEndOfSmi(void);
|
||||
void StartTimer(void);
|
||||
void StopTimer(void);
|
||||
int CheckTimerSTS(UINT32 Index);
|
||||
void ClearTimerSTS(void);
|
||||
void SetMaxSwTimerInt(void);
|
||||
void SetMinSwTimerInt(void);
|
||||
|
@ -109,9 +108,12 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
// load the shared page and region list addresses into the register save area
|
||||
// so that the PE module will access to those addresses
|
||||
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rbx = (UINTN)PeVmData[PeType].UserModule.SharedPage;
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rcx = (UINT64)PeVmData[PeType].UserModule.Segment;
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rdx = (UINTN) PeVmData[PeType].UserModule.SharedStmPage;
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rbx =
|
||||
(UINTN)PeVmData[PeType].UserModule.SharedPage;
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rcx =
|
||||
(UINT64)PeVmData[PeType].UserModule.Segment;
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rdx =
|
||||
(UINTN) PeVmData[PeType].UserModule.SharedStmPage;
|
||||
|
||||
// check and make aure that the heap is cleared as requested
|
||||
|
||||
|
@ -127,39 +129,50 @@ 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", CpuIndex));
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld LaunchPeVM - VM/PE heap space not cleared because of DoNotClearSize too large\n",
|
||||
CpuIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVm - Clearing VM/PE heap space: 0x%016llx:0x%016llx\n", CpuIndex, StartEndBlock, EndSize ));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVm - Clearing VM/PE heap space: 0x%016llx:0x%016llx\n",
|
||||
CpuIndex,
|
||||
StartEndBlock,
|
||||
EndSize ));
|
||||
|
||||
ZeroMem ((VOID *)(UINTN)StartEndBlock, EndSize);
|
||||
}
|
||||
}
|
||||
|
||||
// setup the variables that are used in case an SMI is taken while the PE VM is running
|
||||
// setup the variables that are used in case an SMI is taken
|
||||
// while the PE VM is running
|
||||
|
||||
// this needs to be fixed if more than one PE/VM is running
|
||||
|
||||
PeSmiControl.PeNmiBreak = 1; // when 1, a NMI has been sent to break the thread in PE_APIC_id
|
||||
PeSmiControl.PeApicId = ReadLocalApicId (); // APIC id of the thread that is executing the PE V<
|
||||
// when 1, a NMI has been sent to break the thread in PE_APIC_id
|
||||
PeSmiControl.PeNmiBreak = 1;
|
||||
|
||||
// APIC id of the thread that is executing the PE V<
|
||||
PeSmiControl.PeApicId = ReadLocalApicId ();
|
||||
PeSmiControl.PeCpuIndex = CpuIndex;
|
||||
PeSmiControl.PeExec = 0; // when 1 PE_APIC_ID is executing a
|
||||
VmPeReady = 0; // set the ready gate
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVm - before check PeSmiState: %ld\n", CpuIndex, PeSmiControl.PeSmiState));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVm - before check PeSmiState: %ld\n",
|
||||
CpuIndex,
|
||||
PeSmiControl.PeSmiState));
|
||||
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMIHSMI) == PESMIHSMI) // try to set the NMI
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMIHSMI) == PESMIHSMI) // try to set the NMI
|
||||
{
|
||||
// if we know that the SMI handler is already active, then don't continue
|
||||
// save the state, process the SMI, then start the VM/PE afterwards
|
||||
|
||||
DEBUG((EFI_D_ERROR,"%ld LaunchPeVM - SMI being processed - faking NMI - PeSmiState: %ld\n", CpuIndex, PeSmiControl.PeSmiState));
|
||||
//InterlockedCompareExchange32(&PeSmiControl.PeSmiState, 2, 0); // reset to zero
|
||||
|
||||
//save_Inter_PeVm(CpuIndex);
|
||||
//DEBUG((EFI_D_ERROR, "%ld LaunchPeVM - Return from non-returnable function\n", CpuIndex));
|
||||
//NMIReceived = 2; // If an SMI happens we receive two NMI's so fake it
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVM - SMI being processed - faking NMI - PeSmiState: %ld\n",
|
||||
CpuIndex,
|
||||
PeSmiControl.PeSmiState));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -172,77 +185,113 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
|
||||
// Set InitialStack pointer to the top of User memory...
|
||||
|
||||
InitStackPointer = (UINTN) PeVmData[PeType].UserModule.AddressSpaceStart + (UINTN) PeVmData[PeType].UserModule.AddressSpaceSize - (UINTN) 16;
|
||||
InitStackPointer = (UINTN) PeVmData[PeType].UserModule.AddressSpaceStart +
|
||||
(UINTN) PeVmData[PeType].UserModule.AddressSpaceSize -
|
||||
(UINTN) 16;
|
||||
VmWriteN (VMCS_N_GUEST_RSP_INDEX, InitStackPointer);
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVm- IntialStackPointer: 0x%llx\n", CpuIndex, InitStackPointer));
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVm- VMCS_N_GUEST_RFLAGS_INDEX: %08llx\n", CpuIndex, VmReadN(VMCS_N_GUEST_RFLAGS_INDEX)));
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVm- IA32_EFER_MSR: 0x%llx\n", CpuIndex, AsmReadMsr64 (IA32_EFER_MSR_INDEX)));
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVm- VMCS_32_CONTROL_PIN_BASED_VM_EXECUTION_INDEX: 0x%llx\n", CpuIndex, VmRead32(VMCS_32_CONTROL_PIN_BASED_VM_EXECUTION_INDEX)));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVm- IntialStackPointer: 0x%llx\n",
|
||||
CpuIndex,
|
||||
InitStackPointer));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVm- VMCS_N_GUEST_RFLAGS_INDEX: %08llx\n",
|
||||
CpuIndex,
|
||||
VmReadN(VMCS_N_GUEST_RFLAGS_INDEX)));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVm- IA32_EFER_MSR: 0x%llx\n",
|
||||
CpuIndex,
|
||||
AsmReadMsr64 (IA32_EFER_MSR_INDEX)));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVm- VMCS_32_CONTROL_PIN_BASED_VM_EXECUTION_INDEX: 0x%llx\n",
|
||||
CpuIndex,
|
||||
VmRead32(VMCS_32_CONTROL_PIN_BASED_VM_EXECUTION_INDEX)));
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVm- guest parameter regs:\n RBX: %p (shared page)\n RCX: %p (region list)\n RDX: %p (shared STM)\n",
|
||||
DEBUG((EFI_D_INFO, "%ld LaunchPeVm- guest parameter regs:\n RBX: %p (shared page)\n RCX: %p (region list)\n RDX: %p (shared STM)\n",
|
||||
CpuIndex,
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rbx,
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rcx,
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register.Rdx));
|
||||
|
||||
//SetMinSwTimerInt();
|
||||
PeVmData[PeType].UserModule.RunCount++;
|
||||
// set the runcount into the STM shared page
|
||||
|
||||
*((UINT64 *)(PeVmData[PeType].SharedPageStm + sizeof(UINT64))) = PeVmData[PeType].UserModule.RunCount;
|
||||
*((UINT64 *)(PeVmData[PeType].SharedPageStm + sizeof(UINT64))) =
|
||||
PeVmData[PeType].UserModule.RunCount;
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVM - Initiating PE/VM run number: %d\n",
|
||||
DEBUG((EFI_D_INFO, "%ld LaunchPeVM - Initiating PE/VM run number: %d\n",
|
||||
CpuIndex,
|
||||
PeVmData[PeType].UserModule.RunCount));
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVM - SharedPageStm 0x%016llx 0x%016llx\n",
|
||||
DEBUG((EFI_D_INFO, "%ld LaunchPeVM - SharedPageStm 0x%016llx 0x%016llx\n",
|
||||
CpuIndex,
|
||||
*((UINT64 *)(PeVmData[PeType].SharedPageStm)),
|
||||
*((UINT64 *)(PeVmData[PeType].SharedPageStm + sizeof(UINT64)))));
|
||||
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType = PeType; // Make sure we take the correct path upon RSM
|
||||
// Make sure we take the correct path upon RSM
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType = PeType;
|
||||
|
||||
StartPeTimeStamp = AsmReadTsc(); // set start time
|
||||
|
||||
AsmWbinvd ();
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVm - ***Debug*** VmPE ready for launch PeType %d registers-address: 0x%016llx\n",
|
||||
CpuIndex, PeType, &mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register ));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVm - ***Debug*** VmPE ready for launch PeType %d registers-address: 0x%016llx\n",
|
||||
CpuIndex,
|
||||
PeType,
|
||||
&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register ));
|
||||
|
||||
// need to check to see if an SMI happend during this period
|
||||
// first incidcate that the VM/PE is ready for launch
|
||||
|
||||
VmPeReady = 1; // this will cause the interrupt handler to save the VM/PE and launch the VM/PE once the SMI is handled
|
||||
// this will cause the interrupt handler to save the VM/PE and // launch the VM/PE once the SMI is handled
|
||||
VmPeReady = 1;
|
||||
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIPNMI, PESMIHSMI) == PESMIHSMI)
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIPNMI, PESMIHSMI) == PESMIHSMI)
|
||||
{
|
||||
// if we are here, then an SMI has come in and the system is processing it
|
||||
// we need to get out and let the system process the SMI and then restart
|
||||
|
||||
// PeSmiState = 2 means that the other processors are waitng for us to sync up
|
||||
// so synch and then save up the state for when the processors come out of the SMI
|
||||
// PeSmiState = 2 means that the other processors are waitng for us
|
||||
// to sync up
|
||||
// so synch and then save up the state for when the processors
|
||||
// come out of the SMI
|
||||
|
||||
DEBUG((EFI_D_INFO,"%ld LaunchPeVM - SMI detected during build - delaying launch to handle SMI\n",
|
||||
CpuIndex));
|
||||
|
||||
DEBUG((EFI_D_ERROR,"%ld LaunchPeVM - SMI detected during build - delaying launch to handle SMI\n", CpuIndex));
|
||||
//CpuReadySync(CpuIndex); // synch up
|
||||
save_Inter_PeVm(CpuIndex);
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVM - Warning: Return from non-returnable function\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO, "%ld LaunchPeVM - Warning: Return from non-returnable function\n",
|
||||
CpuIndex));
|
||||
}
|
||||
|
||||
if(NMIReceived > 1) // check to see if we received an NMI during the build proceess - if so, handle the SMI then launch
|
||||
// check to see if we received an NMI during the build proceess -
|
||||
// if so, handle the SMI then launch
|
||||
if(NMIReceived > 1)
|
||||
{
|
||||
DEBUG((EFI_D_ERROR,"%ld LaunchPeVM - NMI detected during build - delaying launch to handle SMI\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld LaunchPeVM - NMI 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", CpuIndex));
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVM - Warning: Return from non-returnable function\n",
|
||||
CpuIndex));
|
||||
// this function should not return
|
||||
}
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld LaunchPeVM - Launching PE/VM - NMIReceived: %d\n", CpuIndex, NMIReceived));
|
||||
DEBUG((EFI_D_INFO, "%ld LaunchPeVM - Launching PE/VM - NMIReceived: %d\n",
|
||||
CpuIndex,
|
||||
NMIReceived));
|
||||
|
||||
Rflags = AsmVmLaunch (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register);
|
||||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - (STM):o(\n", (UINTN)CpuIndex));
|
||||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - !!!LaunchGuestSmm fail for PeVm!!!\n", (UINTN)CpuIndex));
|
||||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - Rflags: (UINTN)CpuIndex, %08llx\n", (UINTN)CpuIndex, Rflags));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld LaunchPeVm - !!!LaunchGuestSmm fail for PeVm!!!\n",
|
||||
CpuIndex));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld LaunchPeVm - Rflags: (UINTN)CpuIndex, %08llx\n",
|
||||
CpuIndex,
|
||||
Rflags));
|
||||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n",
|
||||
(UINTN)CpuIndex,
|
||||
(UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
|
@ -254,13 +303,19 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
|
||||
AcquireSpinLock (&mHostContextCommon.DebugLock);
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - !!!ResumeGuestSmm fail for PeVm!!!\n", (UINTN)CpuIndex));
|
||||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - Rflags: (UINTN)CpuIndex, %08llx\n", (UINTN)CpuIndex, Rflags));
|
||||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n",
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld LaunchPeVm - !!!ResumeGuestSmm fail for PeVm!!!\n",
|
||||
CpuIndex));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld LaunchPeVm - Rflags: (UINTN)CpuIndex, %08llx\n",
|
||||
(UINTN)CpuIndex, Rflags));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld LaunchPeVm - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n",
|
||||
(UINTN)CpuIndex,
|
||||
(UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField (CpuIndex);
|
||||
DumpRegContext (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register, CpuIndex);
|
||||
DumpRegContext (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register,
|
||||
CpuIndex);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
}
|
||||
|
||||
|
@ -274,22 +329,28 @@ STM_STATUS RunPermVM(UINT32 CpuIndex)
|
|||
|
||||
// (for now) start the VM...
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld RunPermVM entered\n", CpuIndex));
|
||||
//VmWriteN (VMCS_N_GUEST_RIP_INDEX, VmReadN (VMCS_N_GUEST_RIP_INDEX) + VmRead32 (VMCS_32_RO_VMEXIT_INSTRUCTION_LENGTH_INDEX));
|
||||
DEBUG((EFI_D_INFO, "%ld RunPermVM entered\n", CpuIndex));
|
||||
|
||||
if(PeVmData[PeType].PeVmState != PE_VM_IDLE )
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld RunPermVM - Can not run a Perm PE/VM\n", CpuIndex));
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld RunPermVM - Can not run a Perm PE/VM\n",
|
||||
CpuIndex));
|
||||
if((PeVmData[PeType].PeVmState == PE_VM_ACTIVE) ||
|
||||
(PeVmData[PeType].PeVmState == PE_VM_SUSPEND))
|
||||
{
|
||||
rc = PE_VM_EXECUTING;
|
||||
DEBUG((EFI_D_ERROR, "%ld RunPermVM - Attempting to execute an already running Perm PE/VM\n", CpuIndex));
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld RunPermVM - Attempting to execute an already running Perm PE/VM\n",
|
||||
CpuIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = PE_VM_NO_PERM_VM;
|
||||
DEBUG((EFI_D_ERROR, "%ld RunPermVM - Attempt to execute a non-existant PE/VM state: %d\n", CpuIndex, PeVmData[PeType].PeVmState));
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld RunPermVM - Attempt to execute a non-existant PE/VM state: %d\n",
|
||||
CpuIndex,
|
||||
PeVmData[PeType].PeVmState));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -307,14 +368,14 @@ STM_STATUS RunPermVM(UINT32 CpuIndex)
|
|||
|
||||
// setup the return
|
||||
|
||||
rc = SetupProtExecVm(CpuIndex, PeVmData[PE_PERM].UserModule.VmConfig, RESTART_VM, PeType); // can only restart PERM_VM
|
||||
rc = SetupProtExecVm(CpuIndex,
|
||||
PeVmData[PE_PERM].UserModule.VmConfig,
|
||||
RESTART_VM,
|
||||
PeType); // can only restart PERM_VM
|
||||
|
||||
if(rc != PE_SUCCESS) // did we have a problem
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld - Error in configuring PE VM\n", CpuIndex));
|
||||
//FreePE_DataStructures(PeType);
|
||||
//setPEerrorCode(rc, StmVmm); // tell the caller of the problem
|
||||
//StmVmm->NonSmiHandler = 0; // no longer an PE VM
|
||||
PeVmData[PeType].PeVmState = PE_VM_AVAIL;
|
||||
return(rc);
|
||||
}
|
||||
|
@ -350,11 +411,26 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
Scale = MultU64x32(PlatformData.Bits.MaxNonTurboRatio, 100000);
|
||||
|
||||
TotalScaleTime = DivU64x32(TotalPeTime, (UINT32) Scale);
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - Platform Data - Max Ratio: %d\n", CpuIndex, PlatformData.Bits.MaxNonTurboRatio));
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - TSC Info - StartPeTimeStamp: %ld EndTimeStamp: %ld\n", CpuIndex, StartPeTimeStamp, EndTimeStamp));
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - PeType: %d mode: %d PE clocktime: %ld runtime(scaled): %ldms\n", CpuIndex, PeType, mode, TotalPeTime, TotalScaleTime));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - Platform Data - Max Ratio: %d\n",
|
||||
CpuIndex,
|
||||
PlatformData.Bits.MaxNonTurboRatio));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - TSC Info - StartPeTimeStamp: %ld EndTimeStamp: %ld\n",
|
||||
CpuIndex,
|
||||
StartPeTimeStamp,
|
||||
EndTimeStamp));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - PeType: %d mode: %d PE clocktime: %ld runtime(scaled): %ldms\n",
|
||||
CpuIndex,
|
||||
PeType,
|
||||
mode,
|
||||
TotalPeTime,
|
||||
TotalScaleTime));
|
||||
|
||||
switch (rc) // dump guest state upon bad return (eventually place in shared area)
|
||||
// Dump guest state upon bad return (eventually place in shared area)
|
||||
|
||||
switch (rc)
|
||||
{
|
||||
case PE_VM_ATTEMPTED_VMCALL:
|
||||
case PE_VMLAUNCH_ERROR:
|
||||
|
@ -370,14 +446,18 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
case PE_VM_EXCEPTION:
|
||||
DumpVmcsAllField(CpuIndex); // temp debug
|
||||
DumpVmxCapabillityMsr(CpuIndex);
|
||||
DumpRegContext(&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register, CpuIndex);
|
||||
DumpRegContext(&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register,
|
||||
CpuIndex);
|
||||
print_region_list(PeType, CpuIndex);
|
||||
|
||||
if((PERM_VM_CRASH_BREAKDOWN & PeVmData[PeType].UserModule.VmConfig) == PERM_VM_CRASH_BREAKDOWN)
|
||||
if((PERM_VM_CRASH_BREAKDOWN & PeVmData[PeType].UserModule.VmConfig) ==
|
||||
PERM_VM_CRASH_BREAKDOWN)
|
||||
{
|
||||
// user wants perm vm released after crash
|
||||
mode = RELEASE_VM;
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - Perm VM configured to be released after crash\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - Perm VM configured to be released after crash\n",
|
||||
CpuIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -401,22 +481,28 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
|
||||
if(mode == PRESERVE_VM)
|
||||
{
|
||||
if((PERM_VM_RUN_ONCE & PeVmData[PeType].UserModule.VmConfig) == PERM_VM_RUN_ONCE)
|
||||
if((PERM_VM_RUN_ONCE & PeVmData[PeType].UserModule.VmConfig) ==
|
||||
PERM_VM_RUN_ONCE)
|
||||
{
|
||||
// user wants perm vm released after crash
|
||||
mode = RELEASE_VM;
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - Perm VM configured to run only once\n", CpuIndex));
|
||||
PeSmiControl.PeCpuIndex = -1; // indicate none functioning at this momemnet
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld PostPeVmProc - Perm VM configured to run only once\n",
|
||||
CpuIndex));
|
||||
|
||||
// indicate none functioning at this momemnet
|
||||
PeSmiControl.PeCpuIndex = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((PERM_VM_RUN_PERIODIC & PeVmData[PeType].UserModule.VmConfig) == PERM_VM_RUN_PERIODIC)
|
||||
if((PERM_VM_RUN_PERIODIC & PeVmData[PeType].UserModule.VmConfig) ==
|
||||
PERM_VM_RUN_PERIODIC)
|
||||
{
|
||||
// the PE/VM is running in periodic mode
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - Perm VM being setup for Timer interrupt\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO, "%ld PostPeVmProc - Perm VM being setup for Timer interrupt\n",
|
||||
CpuIndex));
|
||||
PeSmiControl.PeCpuIndex = CpuIndex;
|
||||
//
|
||||
//InitCpuReadySync(); // Setup the locking
|
||||
PeSmiControl.PeWaitTimer = 1;
|
||||
PeVmData[PeType].PeVmState = PE_VM_IDLE;
|
||||
|
||||
|
@ -435,10 +521,15 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
// suspending PE/VM so that SMI handler can run
|
||||
|
||||
PeVmData[PeType].PeVmState = PE_VM_SUSPEND;
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - PE/VM suspended - PeType: %ld\n", CpuIndex, PeType));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - PE/VM suspended - PeType: %ld\n",
|
||||
CpuIndex,
|
||||
PeType));
|
||||
|
||||
// we will fake a return to the MLE - that will cause the pending SMI to fire allowing
|
||||
// the smiEvent handler to process is and release all the processor threads
|
||||
// we will fake a return to the MLE -
|
||||
// that will cause the pending SMI to fire allowing
|
||||
// the smiEvent handler to process it and release all
|
||||
// he processor threads
|
||||
// to handle the SMI
|
||||
|
||||
AsmVmPtrLoad(&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Vmcs);
|
||||
|
@ -447,48 +538,16 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
|
||||
AsmVmClear(&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Vmcs);
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "%ld PostPeVmProc - !!exiting to allow SMI to fire to Enter SmiHandler\n", CpuIndex));
|
||||
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - !!exiting to allow SMI to fire to Enter SmiHandler\n",
|
||||
CpuIndex));
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType = SMI_HANDLER;
|
||||
#ifdef OLDWAY
|
||||
// set the SMI/Handler VMCS intoplace (note copied the Intel code - need to fix duplication...
|
||||
|
||||
STM_PERF_START (CpuIndex, 0, "WriteSyncSmmStateSaveArea", "SmiEventHandler");
|
||||
WriteSyncSmmStateSaveArea (CpuIndex);
|
||||
STM_PERF_END (CpuIndex, "WriteSyncSmmStateSaveArea", "SmiEventHandler");
|
||||
|
||||
AsmVmPtrStore (&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Vmcs);
|
||||
Rflags = AsmVmPtrLoad (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Vmcs);
|
||||
if ((Rflags & (RFLAGS_CF | RFLAGS_ZF)) != 0) {
|
||||
DEBUG ((EFI_D_ERROR, "%ld PostPeVmProc - ERROR: AsmVmPtrLoad - %016lx : %08x\n", (UINTN)CpuIndex, mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Vmcs, Rflags));
|
||||
DEBUG((EFI_D_ERROR, "%ld, PostPeVmProc - CpuDeadLoop\n", CpuIndex));
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
VmWriteN (VMCS_N_GUEST_RIP_INDEX, (UINTN)mHostContextCommon.HostContextPerCpu[CpuIndex].TxtProcessorSmmDescriptor->SmmSmiHandlerRip);
|
||||
VmWriteN (VMCS_N_GUEST_RSP_INDEX, (UINTN)mHostContextCommon.HostContextPerCpu[CpuIndex].TxtProcessorSmmDescriptor->SmmSmiHandlerRsp);
|
||||
VmWriteN (VMCS_N_GUEST_CR3_INDEX, mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Cr3);
|
||||
|
||||
STM_PERF_START (CpuIndex, 0, "BiosSmmHandler", "SmiEventHandler");
|
||||
|
||||
if (mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Launched) {
|
||||
Rflags = AsmVmResume (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register);
|
||||
// BUGBUG: - AsmVmLaunch if AsmVmResume fail
|
||||
if (VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX) == VmxFailErrorVmResumeWithNonLaunchedVmcs) {
|
||||
// DEBUG ((EFI_D_ERROR, "(STM):-(\n", (UINTN)Index));
|
||||
Rflags = AsmVmLaunch (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register);
|
||||
}
|
||||
} else {
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Launched = TRUE;
|
||||
Rflags = AsmVmLaunch (&mGuestContextCommonSmm[0].GuestContextPerCpu[CpuIndex].Register);
|
||||
mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Launched = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**/
|
||||
if (mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Launched) {
|
||||
Rflags = AsmVmResume (&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Register);
|
||||
// BUGBUG: - AsmVmLaunch if AsmVmResume fail
|
||||
if (VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX) == VmxFailErrorVmResumeWithNonLaunchedVmcs) {
|
||||
if (VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX) ==
|
||||
VmxFailErrorVmResumeWithNonLaunchedVmcs) {
|
||||
// DEBUG ((EFI_D_ERROR, "(STM):-(\n", (UINTN)Index));
|
||||
Rflags = AsmVmLaunch (&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Register);
|
||||
}
|
||||
|
@ -512,12 +571,15 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
{
|
||||
// fixup return address
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - PE/VM guest return address bumped\n", CpuIndex));
|
||||
VmWriteN (VMCS_N_GUEST_RIP_INDEX, VmReadN (VMCS_N_GUEST_RIP_INDEX) + VmRead32 (VMCS_32_RO_VMEXIT_INSTRUCTION_LENGTH_INDEX));
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld PostPeVmProc - PE/VM guest return address bumped\n",
|
||||
CpuIndex));
|
||||
VmWriteN (VMCS_N_GUEST_RIP_INDEX,
|
||||
VmReadN (VMCS_N_GUEST_RIP_INDEX) +
|
||||
VmRead32 (VMCS_32_RO_VMEXIT_INSTRUCTION_LENGTH_INDEX));
|
||||
|
||||
}
|
||||
}
|
||||
//DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - guest return address is %p\n", CpuIndex, VmReadN(VMCS_N_GUEST_RIP_INDEX)));
|
||||
// clear out the page table list
|
||||
if(mode == RELEASE_VM)
|
||||
{
|
||||
|
@ -526,17 +588,20 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
// so that in production someone cannot take advantange of this case
|
||||
PeVmData[PeType].PeVmState = PE_VM_AVAIL; // not there anymore
|
||||
PeSmiControl.PeCpuIndex = -1; // indicate none functioning at this momemnet
|
||||
//keep the old vmcs around - think about clearing...
|
||||
//FreePages((UINTN *)mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Vmcs, 2);
|
||||
//mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Vmcs = 0L; // not there any more
|
||||
DEBUG((EFI_D_INFO, "%ld PostPeVmProc - PE/VM Free (AVAIL) - PeType: %ld\n", CpuIndex, PeType));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - PE/VM Free (AVAIL) - PeType: %ld\n",
|
||||
CpuIndex,
|
||||
PeType));
|
||||
}
|
||||
else
|
||||
{
|
||||
// mark this VM as idle
|
||||
|
||||
PeVmData[PeType].PeVmState = PE_VM_IDLE; // Waiting for more actio
|
||||
DEBUG((EFI_D_INFO, "%ld PostPeVmProc - PE/VM Idle - PeType: %ld\n", CpuIndex, PeType));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - PE/VM Idle - PeType: %ld\n",
|
||||
CpuIndex,
|
||||
PeType));
|
||||
}
|
||||
|
||||
if(PeVmData[PeType].StartMode == PEVM_START_VMCALL)
|
||||
|
@ -548,18 +613,24 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
WriteUnaligned32 ((UINT32 *)&Reg->Rax, rc);
|
||||
if (rc == PE_SUCCESS)
|
||||
{
|
||||
VmWriteN (VMCS_N_GUEST_RFLAGS_INDEX, VmReadN(VMCS_N_GUEST_RFLAGS_INDEX) & ~RFLAGS_CF);
|
||||
VmWriteN (VMCS_N_GUEST_RFLAGS_INDEX,
|
||||
VmReadN(VMCS_N_GUEST_RFLAGS_INDEX) & ~RFLAGS_CF);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - Unsucessful return noted in RFLAGS_CF\n", CpuIndex));
|
||||
VmWriteN (VMCS_N_GUEST_RFLAGS_INDEX, VmReadN(VMCS_N_GUEST_RFLAGS_INDEX) | RFLAGS_CF);
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - Unsucessful return noted in RFLAGS_CF\n",
|
||||
CpuIndex));
|
||||
VmWriteN (VMCS_N_GUEST_RFLAGS_INDEX,
|
||||
VmReadN(VMCS_N_GUEST_RFLAGS_INDEX) | RFLAGS_CF);
|
||||
}
|
||||
}
|
||||
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType = SMI_HANDLER;
|
||||
DEBUG((EFI_D_INFO, "%ld PostPeVmProc - sucessfully completed - RC: 0x%x\n", CpuIndex, rc));
|
||||
//StopSwTimer();
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - sucessfully completed - RC: 0x%x\n",
|
||||
CpuIndex,
|
||||
rc));
|
||||
CheckPendingMtf (CpuIndex);
|
||||
|
||||
//
|
||||
|
@ -567,29 +638,44 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
//
|
||||
Rflags = AsmVmResume (&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Register);
|
||||
// BUGBUG: - AsmVmLaunch if AsmVmResume fail
|
||||
if (VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX) == VmxFailErrorVmResumeWithNonLaunchedVmcs) {
|
||||
DEBUG ((EFI_D_ERROR, "%ld PostPeVmProc - Rflags: %08x\n", CpuIndex, Rflags));
|
||||
DEBUG ((EFI_D_ERROR, "%ld PostPeVmProc - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n",
|
||||
CpuIndex,
|
||||
(UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DEBUG ((EFI_D_ERROR, "%ld PostPeVmProc - (STM):o(\n", (UINTN)CpuIndex));
|
||||
if (VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX) ==
|
||||
VmxFailErrorVmResumeWithNonLaunchedVmcs) {
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld PostPeVmProc - Rflags: %08x\n",
|
||||
CpuIndex,
|
||||
Rflags));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld PostPeVmProc - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n",
|
||||
CpuIndex,
|
||||
(UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld PostPeVmProc - (STM):o(\n",
|
||||
(UINTN)CpuIndex));
|
||||
Rflags = AsmVmLaunch (&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Register);
|
||||
}
|
||||
|
||||
AcquireSpinLock (&mHostContextCommon.DebugLock);
|
||||
DEBUG ((EFI_D_ERROR, "%ld PostPeVmProc - !!!PePostVmProcessing FAIL!!!\n", CpuIndex));
|
||||
DEBUG ((EFI_D_ERROR, "%ld PostPeVmProc - Rflags: %08x\n", CpuIndex, Rflags));
|
||||
DEBUG ((EFI_D_ERROR, "%ld PostPeVmProc - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n",
|
||||
CpuIndex,
|
||||
(UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld PostPeVmProc - !!!PePostVmProcessing FAIL!!!\n",
|
||||
CpuIndex));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld PostPeVmProc - Rflags: %08x\n",
|
||||
CpuIndex,
|
||||
Rflags));
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%ld PostPeVmProc - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n",
|
||||
CpuIndex,
|
||||
(UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
|
||||
DumpVmcsAllField (CpuIndex);
|
||||
DumpRegContext (&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Register, CpuIndex);
|
||||
DumpRegContext (&mGuestContextCommonSmi.GuestContextPerCpu[CpuIndex].Register,
|
||||
CpuIndex);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
DEBUG((EFI_D_ERROR, "%ld PostPeVmProc - CpuDeadLoop\n"));
|
||||
CpuDeadLoop (); // crash here because we cannot get back to the MLE...
|
||||
|
||||
// check to see if there is a path through the intel code for going back to the MLE
|
||||
// check to see if there is a path through the intel code
|
||||
// for going back to the MLE
|
||||
|
||||
return rc; // always succeed
|
||||
}
|
||||
|
@ -628,13 +714,17 @@ UINT32 save_Inter_PeVm(UINT32 CpuIndex)
|
|||
// come here when the VM has been interrupted by an SMI
|
||||
// setup for the call to PostPeVmProc
|
||||
|
||||
UINT32 PeType = mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType; // which PT are we using
|
||||
// which PT are we using
|
||||
UINT32 PeType = mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType;
|
||||
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].NonSmiHandler = PeType; // let the STM know that we are waiting to come back
|
||||
// let the STM know that we are waiting to come back
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].NonSmiHandler = PeType;
|
||||
|
||||
EndTimeStamp = AsmReadTsc();
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld save_Inter_PeVm - sucessfully completed\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld save_Inter_PeVm - sucessfully completed\n",
|
||||
CpuIndex));
|
||||
|
||||
PostPeVmProc(PE_SUCCESS, CpuIndex, SUSPEND_VM);
|
||||
|
||||
|
@ -652,12 +742,18 @@ UINT32 RestoreInterPeVm(UINT32 CpuIndex, UINT32 PeType)
|
|||
{
|
||||
// should only happen when the PEV/VM is initially loaded, otherwise
|
||||
// this informaition should be normally grabbed upon a smi timer interrupt
|
||||
// bug - need to consider the case of debug loading of a module for testing
|
||||
// bug -
|
||||
// need to consider the case of debug loading of a module for testing
|
||||
|
||||
if(GetMultiProcessorState(CpuIndex) == -1)
|
||||
{
|
||||
GetMPState = 1; // Indicate that we still need to get the processor state
|
||||
return 1; // in this case there is an SMI in process and we need to let it be processed.
|
||||
// Indicate that we still need to get the processor state
|
||||
GetMPState = 1;
|
||||
|
||||
// in this case there is an SMI in process and
|
||||
// we need to let it be processed.
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -666,36 +762,49 @@ UINT32 RestoreInterPeVm(UINT32 CpuIndex, UINT32 PeType)
|
|||
}
|
||||
}
|
||||
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMIHSMI) == PESMIHSMI)
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState,
|
||||
PESMIHSMI, PESMIHSMI) == PESMIHSMI)
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld RestoreInterPeVm - SMI in progress - aborting PE/VM restart\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld RestoreInterPeVm - SMI in progress - aborting PE/VM restart\n",
|
||||
CpuIndex));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// need to think about locking here in case there are two smi's in a row...
|
||||
PeVmData[PeType].PeVmState = PE_VM_ACTIVE;
|
||||
PeSmiControl.PeNmiBreak = 1; // when 1, a NMI has been sent to break the thread in PE_APIC_id
|
||||
PeSmiControl.PeApicId = ReadLocalApicId (); // APIC id of the thread that is executing the PE V<
|
||||
|
||||
// when 1, a NMI has been sent to break the thread in PE_APIC_id
|
||||
PeSmiControl.PeNmiBreak = 1;
|
||||
|
||||
// APIC id of the thread that is executing the PE V<
|
||||
PeSmiControl.PeApicId = ReadLocalApicId ();
|
||||
|
||||
PeSmiControl.PeCpuIndex = CpuIndex;
|
||||
//PeSmiControl.PeExec = 0; // when 1 PE_APIC_ID is executing a
|
||||
|
||||
// think about break code (BUG)
|
||||
|
||||
VmPeReady = 0; // set the ready gate (for here do not get out (BUG - Review this!!! for SMI in this interval)
|
||||
// set the ready gate (for here do not get out
|
||||
// (BUG - Review this!!! for SMI in this interval)
|
||||
VmPeReady = 0;
|
||||
enable_nmi(); // turn on NMI
|
||||
|
||||
PeSmiControl.PeNmiBreak = 0; // when 1, a NMI has been sent to break the thread in PE_APIC_id
|
||||
// when 1, a NMI has been sent to break the thread in PE_APIC_id
|
||||
PeSmiControl.PeNmiBreak = 0;
|
||||
PeSmiControl.PeExec = 1; // when 1 PE_APIC_ID is executing a
|
||||
// setup the return
|
||||
|
||||
AsmVmPtrLoad(&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Vmcs);
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType = PeType;
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld RestoreInterPeVm - setup done, launching PE/VM\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO, "%ld RestoreInterPeVm - setup done, launching PE/VM\n",
|
||||
CpuIndex));
|
||||
// Launch back
|
||||
//
|
||||
Rflags = AsmVmResume (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register);
|
||||
// BUGBUG: - AsmVmLaunch if AsmVmResume fail
|
||||
if (VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX) == VmxFailErrorVmResumeWithNonLaunchedVmcs) {
|
||||
if (VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX) ==
|
||||
VmxFailErrorVmResumeWithNonLaunchedVmcs) {
|
||||
// DEBUG ((EFI_D_ERROR, "(STM):o(\n", (UINTN)Index));
|
||||
Rflags = AsmVmLaunch (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register);
|
||||
}
|
||||
|
@ -714,22 +823,28 @@ void print_region_list(UINT32 PeType, UINT32 CpuIndex)
|
|||
|
||||
if(rlist == NULL)
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld - No region list\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO, "%ld - No region list\n", CpuIndex));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld --- Region List --- \n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO, "%ld --- Region List --- \n", CpuIndex));
|
||||
|
||||
for(counter = 0; counter < (4096/sizeof(PE_REGION_LIST)); counter++)
|
||||
{
|
||||
if(rlist[counter].Address == (UINT64) 0)
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, "%ld Finish scanning Region List - %d elements found\n", CpuIndex, counter));
|
||||
DEBUG((EFI_D_INFO, "%ld Finish scanning Region List - %d elements found\n",
|
||||
CpuIndex,
|
||||
counter));
|
||||
break; // done at end of list
|
||||
}
|
||||
|
||||
EndAddress = rlist[counter].Address + rlist[counter].Size;
|
||||
DEBUG((EFI_D_ERROR, "%ld region set at 0x%016llx:%016llx - size 0x%016lx\n", CpuIndex, rlist[counter].Address, EndAddress, rlist[counter].Size));
|
||||
DEBUG((EFI_D_INFO, "%ld region set at 0x%016llx:%016llx size 0x%016lx\n",
|
||||
CpuIndex,
|
||||
rlist[counter].Address,
|
||||
EndAddress,
|
||||
rlist[counter].Size));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -744,7 +859,7 @@ void enable_nmi()
|
|||
// the interrupt is fired
|
||||
|
||||
while(NMIReceived == 0) {} // wait for NMI interrupt
|
||||
DEBUG((EFI_D_ERROR, "NMI handler active\n"));
|
||||
DEBUG((EFI_D_INFO, "NMI handler active\n"));
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -755,19 +870,24 @@ VOID
|
|||
)
|
||||
{
|
||||
NMIReceived = NMIReceived + 1; // increment
|
||||
DEBUG((EFI_D_ERROR, "***NMI***Happened****\n"));
|
||||
//DEBUG((EFI_D_INFO, "***NMI***Happened****\n"));
|
||||
|
||||
if(VmPeReady == 1)
|
||||
{
|
||||
|
||||
UINT32 CpuIndex = ApicToIndex (ReadLocalApicId ());
|
||||
// in this instance, the VmPe is ready for launch, but an SMI has appeared after the NMI has
|
||||
// been enabled, but during the iteval between VM/PE setup complete and its launch
|
||||
// so we will hold the launch, service the SMI and then launch the VM/PE once the
|
||||
// in this instance, the VmPe is ready for launch,
|
||||
// but an SMI has appeared after the NMI has
|
||||
// been enabled, but during the iterval between
|
||||
// VM/PE setup complete and its launch
|
||||
// so we will hold the launch, service the SMI and
|
||||
// then launch the VM/PE once the
|
||||
// SMI is handled
|
||||
|
||||
save_Inter_PeVm(CpuIndex);
|
||||
DEBUG((EFI_D_ERROR, "%ld enable_nmi - Return from non-returnable function\n", CpuIndex));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld enable_nmi - Return from non-returnable function\n",
|
||||
CpuIndex));
|
||||
|
||||
// this function should not return...
|
||||
}
|
||||
|
@ -806,5 +926,5 @@ void InitPe()
|
|||
|
||||
InitializeSpinLock (&PeSmiControl.PeSmiControlLock);
|
||||
|
||||
DEBUG((EFI_D_ERROR, "InitPe - PE initialization complete\n"));
|
||||
DEBUG((EFI_D_INFO, "InitPe - PE initialization complete\n"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue