mirror of https://review.coreboot.org/STM.git
Merge branch 'multiSmi' into stmpe-unstable
This commit is contained in:
commit
6d2d68bc37
|
@ -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
|
||||
|
||||
|
@ -143,12 +145,16 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -158,7 +164,8 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
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
|
||||
|
@ -206,11 +213,11 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
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_INFO,
|
||||
"%ld LaunchPeVM - Initiating PE/VM run number: %d\n",
|
||||
|
@ -223,21 +230,25 @@ void LaunchPeVm(UINT32 PeType, UINT32 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_INFO,
|
||||
"%ld LaunchPeVm - ***Debug*** VmPE ready for launch PeType %d registers-address: 0x%016llx\n",
|
||||
"%ld LaunchPeVm - 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, PESMINULL, PESMIPNMI) == PESMIHSMI) //old PESMIPNMI, PESMIPNMI
|
||||
{
|
||||
|
@ -259,7 +270,9 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
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_INFO,
|
||||
"%ld LaunchPeVM - NMI detected during build - delaying launch to handle SMI\n",
|
||||
|
@ -283,8 +296,13 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
|
||||
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)));
|
||||
|
@ -308,7 +326,8 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
(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);
|
||||
}
|
||||
|
||||
|
@ -326,7 +345,8 @@ STM_STATUS RunPermVM(UINT32 CpuIndex)
|
|||
"%ld RunPermVM entered\n",
|
||||
CpuIndex));
|
||||
|
||||
if(PeVmData[PeType].PeVmState != PE_VM_IDLE )
|
||||
if((PeVmData[PeType].PeVmState != PE_VM_IDLE) &&
|
||||
(PeVmData[PeType].PeVmState != PE_VM_WAIT_START))
|
||||
{
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld RunPermVM - Can not run a Perm PE/VM\n",
|
||||
|
@ -363,7 +383,10 @@ 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
|
||||
{
|
||||
|
@ -422,7 +445,9 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 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:
|
||||
|
@ -438,10 +463,12 @@ 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;
|
||||
|
@ -471,24 +498,29 @@ 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_INFO,
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"%ld PostPeVmProc - Perm VM configured to run only once\n",
|
||||
CpuIndex));
|
||||
PeSmiControl.PeCpuIndex = -1; // indicate none functioning at this momemnet
|
||||
|
||||
// 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_INFO,
|
||||
"%ld PostPeVmProc - Perm VM being setup for Timer interrupt\n",
|
||||
CpuIndex));
|
||||
PeSmiControl.PeCpuIndex = CpuIndex;
|
||||
//
|
||||
PeSmiControl.PeWaitTimer = 1;
|
||||
PeVmData[PeType].PeVmState = PE_VM_IDLE;
|
||||
|
||||
|
@ -513,8 +545,10 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
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);
|
||||
|
@ -531,7 +565,8 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
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);
|
||||
}
|
||||
|
@ -563,7 +598,6 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
VmRead32 (VMCS_32_RO_VMEXIT_INSTRUCTION_LENGTH_INDEX));
|
||||
}
|
||||
}
|
||||
//DEBUG((EFI_D_INFO, "%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)
|
||||
{
|
||||
|
@ -572,9 +606,6 @@ 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,
|
||||
|
@ -600,23 +631,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_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);
|
||||
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",
|
||||
"%ld PostPeVmProc - sucessfully completed - RC: 0x%x\n",
|
||||
CpuIndex,
|
||||
rc));
|
||||
//StopSwTimer();
|
||||
CheckPendingMtf (CpuIndex);
|
||||
|
||||
//
|
||||
|
@ -624,30 +656,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,
|
||||
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
|
||||
}
|
||||
|
@ -686,9 +732,12 @@ 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;
|
||||
|
||||
// let the STM know that we are waiting to come back
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].NonSmiHandler = PeType;
|
||||
mHostContextCommon.HostContextPerCpu[CpuIndex].NonSmiHandler = PeType;
|
||||
|
||||
EndTimeStamp = AsmReadTsc();
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
|
@ -711,12 +760,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
|
||||
{
|
||||
|
@ -725,7 +780,8 @@ UINT32 RestoreInterPeVm(UINT32 CpuIndex, UINT32 PeType)
|
|||
}
|
||||
}
|
||||
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMIHSMI) == PESMIHSMI)
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState,
|
||||
PESMIHSMI, PESMIHSMI) == PESMIHSMI)
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld RestoreInterPeVm - SMI in progress - aborting PE/VM restart\n",
|
||||
|
@ -735,16 +791,24 @@ UINT32 RestoreInterPeVm(UINT32 CpuIndex, UINT32 PeType)
|
|||
|
||||
// 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
|
||||
|
||||
|
@ -758,7 +822,8 @@ UINT32 RestoreInterPeVm(UINT32 CpuIndex, UINT32 PeType)
|
|||
//
|
||||
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);
|
||||
}
|
||||
|
@ -827,21 +892,24 @@ VOID
|
|||
)
|
||||
{
|
||||
NMIReceived = NMIReceived + 1; // increment
|
||||
DEBUG((EFI_D_INFO,
|
||||
"***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_INFO,
|
||||
"%ld enable_nmi - Return from non-returnable function\n", CpuIndex));
|
||||
"%ld enable_nmi - Return from non-returnable function\n",
|
||||
CpuIndex));
|
||||
|
||||
// this function should not return...
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#define PE_VM_SUSPEND 5 // PE VM is suspended because of SMI
|
||||
#define PE_VM_OPT_OUT_PERM 6 // Perm PE VM Opt Out
|
||||
#define PE_VM_OPT_OUT_TEMP 7 // Temp PE VM Opt Out
|
||||
#define PE_VM_WAIT_START 8 // PE VM is waiting to start
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short int word;
|
||||
|
|
|
@ -120,11 +120,13 @@ UINT16 get_pmbase(void)
|
|||
(STM_RSC *)mGuestContextCommonSmm[SMI_HANDLER].BiosHwResourceRequirementsPtr,
|
||||
IO_RANGE);
|
||||
if(Resource == NULL)
|
||||
DEBUG((EFI_D_ERROR, "get_pmbase - Error pmbase not found in resource list\n"));
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"get_pmbase - Error pmbase not found in resource list\n"));
|
||||
else
|
||||
{
|
||||
pmbase = Resource->Io.Base;
|
||||
DEBUG((EFI_D_INFO, "get_pmbase - pmbase set at 0x%x\n", pmbase));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"get_pmbase - pmbase set at 0x%x\n", pmbase));
|
||||
}
|
||||
}
|
||||
return pmbase;
|
||||
|
@ -137,8 +139,12 @@ void StartTimer(void)
|
|||
UINT32 smi_sts = IoRead32(pmbase + SMI_STS);
|
||||
|
||||
smi_en |= PERIODIC_EN;
|
||||
|
||||
//DEBUG((EFI_D_INFO, "StartTimer - smi_en: 0x%08lx smi_sts: 0x%08lx\n", smi_en, smi_sts));
|
||||
#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);
|
||||
IoWrite32(pmbase + SMI_EN, smi_en);
|
||||
}
|
||||
|
@ -149,18 +155,29 @@ void SetEndOfSmi(void)
|
|||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
smi_en |= EOS_EN; // set the bit
|
||||
|
||||
//DEBUG((EFI_D_INFO, "-- SetEndOfSmi pmbase: %x smi_en: %x \n", pmbase, smi_en));
|
||||
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
"-- SetEndOfSmi pmbase: %x smi_en: %x \n",
|
||||
pmbase,
|
||||
smi_en));
|
||||
#endif
|
||||
IoWrite32(pmbase + SMI_EN, smi_en);
|
||||
//DEBUG((EFI_D_INFO, "SetEndOfSmi smi_en: 0x%08lx smi_sts: 0x%08lx\n", IoRead32(pmbase + SMI_EN), IoRead32(pmbase + SMI_STS)));
|
||||
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
"SetEndOfSmi smi_en: 0x%08lx smi_sts: 0x%08lx\n",
|
||||
IoRead32(pmbase + SMI_EN),
|
||||
IoRead32(pmbase + SMI_STS)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrintSmiEnRegister(UINT32 Index)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
DEBUG((EFI_D_INFO, "%ld PrintSmiEnRegister smi_en: 0x%08x smi_sts: 0x%08x\n", Index, IoRead32(pmbase + SMI_EN), IoRead32(pmbase + SMI_STS)));
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PrintSmiEnRegister smi_en: 0x%08x smi_sts: 0x%08x\n",
|
||||
Index,
|
||||
IoRead32(pmbase + SMI_EN),
|
||||
IoRead32(pmbase + SMI_STS)));
|
||||
}
|
||||
|
||||
void AckTimer(void)
|
||||
|
@ -168,8 +185,12 @@ void AckTimer(void)
|
|||
UINT16 pmbase = get_pmbase();
|
||||
|
||||
IoWrite32(pmbase + SMI_STS, PERIODIC_STS);
|
||||
|
||||
//DEBUG((EFI_D_INFO, "AckTimer - smi_en: 0x%08lx smi_sts: 0x%08lx\n", IoRead32(pmbase + SMI_EN), IoRead32(pmbase + SMI_STS)));
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
"AckTimer - smi_en: 0x%08lx smi_sts: 0x%08lx\n",
|
||||
IoRead32(pmbase + SMI_EN),
|
||||
IoRead32(pmbase + SMI_STS)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void StopSwTimer(void)
|
||||
|
@ -181,21 +202,54 @@ void StopSwTimer(void)
|
|||
IoWrite32(pmbase + SMI_EN, smi_en);
|
||||
}
|
||||
|
||||
/*
|
||||
* CheckTimerSTS
|
||||
* Input:
|
||||
* Index - cpu number
|
||||
*
|
||||
* Output:
|
||||
* 0 - No timer interrupt detected
|
||||
* 1 - Timer interrupt detected
|
||||
* 2 - Timer interrupt plus additional SMI
|
||||
*/
|
||||
|
||||
int CheckTimerSTS(UINT32 Index)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_sts = IoRead32(pmbase + SMI_STS);
|
||||
|
||||
//DEBUG((EFI_D_DEBUG, "%ld CheckTimerSTS - 0x%08lx\n", Index, smi_sts));
|
||||
|
||||
#if 0
|
||||
DEBUG((EFI_D_ERROR, "%ld CheckTimerSTS - 0x%08lx\n", Index, smi_sts));
|
||||
#endif
|
||||
if((smi_sts & PERIODIC_STS) == PERIODIC_STS)
|
||||
{
|
||||
DEBUG((EFI_D_INFO, "%ld CheckTimerSTS - Timer Interrupt Detected\n", Index, smi_sts));
|
||||
return 1;
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
UINT32 other_smi = (smi_en & smi_sts) & ~PERIODIC_STS;
|
||||
|
||||
if(other_smi == 0)
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - Timer Interrupt Detected\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - Timer + other SMI found\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//DEBUG((EFI_D_INFO "%ld CheckTimerSTS - No Timer Interrupt Detected\n", Index, smi_sts));
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - No Timer Interrupt Detected\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -203,8 +257,9 @@ int CheckTimerSTS(UINT32 Index)
|
|||
void ClearTimerSTS()
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
|
||||
IoWrite32(pmbase + SMI_STS, PERIODIC_STS); // just want to clear the status - do not touch the rest
|
||||
|
||||
// just want to clear the status - do not touch the rest
|
||||
IoWrite32(pmbase + SMI_STS, PERIODIC_STS);
|
||||
}
|
||||
|
||||
void SetMaxSwTimerInt()
|
||||
|
|
|
@ -41,27 +41,29 @@ UINT32 PeSmiHandler(UINT32 CpuIndex)
|
|||
UINT64 * NumProcessors;
|
||||
UINT32 PeType = PE_PERM;
|
||||
UINT32 CpuNum;
|
||||
UINT32 TimerSTS = 0;
|
||||
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMINULL, PESMIHSMI);
|
||||
//DEBUG((EFI_D_DEBUG, "%ld PeSmiHandler - CurrPeSmiState %ld\n", CpuIndex, PeSmiControl.PeSmiState));
|
||||
//DEBUG((EFI_D_INFO, "%ld PeSmiHandler - CurrPeSmiState %ld\n", CpuIndex, PeSmiControl.PeSmiState));
|
||||
|
||||
if(PeSmiControl.PeCpuIndex == (INT32)CpuIndex ) // when the pe/vm comes in...
|
||||
{
|
||||
// The VM/PE comes in here and causes the state to be set to null
|
||||
//DEBUG((EFI_D_DEBUG, "%ld PeSmiHandler - VM/PE responded to SMI, CurrPeSmiState %ld\n", CpuIndex, PeSmiControl.PeSmiState));
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PeSmiHandler - VM/PE responded to SMI, CurrPeSmiState %ld\n",
|
||||
CpuIndex,
|
||||
PeSmiControl.PeSmiState));
|
||||
#endif
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIPNMI2, PESMINULL);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
CpuReadySync(CpuIndex); // everyone waits until processor 0 figures out what to do
|
||||
|
@ -73,17 +75,19 @@ UINT32 PeSmiHandler(UINT32 CpuIndex)
|
|||
// VM/PE sends a SMI to the other processors when it wants state information from other CPU's
|
||||
|
||||
NumProcessors = (UINT64 *) PeVmData[PeType].SharedPageStm;
|
||||
RootState = (ROOT_VMX_STATE *) ((char *)NumProcessors + 64);//sizeof(*NumProcessors) + sizeof(*NumProcessors));
|
||||
|
||||
//sizeof(*NumProcessors) + sizeof(*NumProcessors));
|
||||
RootState = (ROOT_VMX_STATE *) ((char *)NumProcessors + 64);
|
||||
|
||||
// get the local processor state
|
||||
|
||||
GetRootVmxState(CpuIndex, &RootState[CpuIndex]);
|
||||
|
||||
//retvalue = 1; // we did something
|
||||
CpuReadySync(CpuIndex); // wait for everyone to finish
|
||||
if(CpuIndex == 0)
|
||||
{
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIPSMI, PESMINULL); // reset the state
|
||||
// Reset the state
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIPSMI, PESMINULL);
|
||||
}
|
||||
return 1; // tell the SmiEventHandler that there is one less processor
|
||||
|
||||
|
@ -97,48 +101,34 @@ UINT32 PeSmiHandler(UINT32 CpuIndex)
|
|||
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeWaitTimer, 1, 1) == 1)
|
||||
{
|
||||
if(CheckTimerSTS(CpuIndex) != 0)
|
||||
{
|
||||
//DEBUG((EFI_D_DEBUG, "%ld CheckAndGetState - (PESMIHSMI) Processing VM/PE startup PeSmiState: %d\n", CpuIndex, PeSmiControl.PeSmiState));
|
||||
TimerSTS = CheckTimerSTS(CpuIndex);
|
||||
|
||||
if (TimerSTS == 2)
|
||||
{
|
||||
// we have an additional SMI
|
||||
InterlockedCompareExchange32 (&retvalue, 1, 0);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
InterlockedCompareExchange32 (&retvalue, 0, 1);
|
||||
}
|
||||
|
||||
if(TimerSTS != 0)
|
||||
{
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld CheckAndGetState - (PESMIHSMI) Processing VM/PE startup PeSmiState: %d\n",
|
||||
CpuIndex,
|
||||
PeSmiControl.PeSmiState));
|
||||
#endif
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMIHTMR);
|
||||
|
||||
NumProcessors = (UINT64 *) PeVmData[PeType].SharedPageStm;
|
||||
RootState = (ROOT_VMX_STATE *) ((char *)NumProcessors + 64);//sizeof(*NumProcessors) + sizeof(*NumProcessors));
|
||||
|
||||
// get the local processor state
|
||||
|
||||
GetRootVmxState(CpuIndex, &RootState[CpuIndex]);
|
||||
|
||||
InterlockedCompareExchange32(&retvalue, 0, 1); // we set to one to indicate we are not there
|
||||
|
||||
// the VM/PE Cpu cleans up and runs
|
||||
//PeSmiControl.PeWaitTimer = 0;
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeWaitTimer, 1, 0);
|
||||
//ClearSwTimerSTS();
|
||||
StopSwTimer();
|
||||
retvalue = 1;
|
||||
// start the VM/PE
|
||||
PeVmData[PeType].StartMode = PEVM_PRESTART_SMI; // starting from SMI
|
||||
CpuReadySync(CpuIndex); // sync everyone ud
|
||||
SetEndOfSmi(); // make sure that the timer SMI has been cleared
|
||||
|
||||
for(CpuNum = 0; CpuNum < mHostContextCommon.CpuNum; CpuNum++)
|
||||
{
|
||||
PrintVmxState(CpuNum, &RootState[CpuNum]);
|
||||
}
|
||||
|
||||
if( mHostContextCommon.StmShutdown == 1)
|
||||
{
|
||||
// time to quit
|
||||
StmTeardown(CpuIndex);
|
||||
}
|
||||
|
||||
RunPermVM(CpuIndex);
|
||||
//PeVmData[PeType].StartMode = PEVM_START_SMI; // for consistency in error conditions
|
||||
//CpuDeadLoop ();
|
||||
// should not get here...
|
||||
return retvalue; // tell the SmiEventHandler that there is one less processor
|
||||
//sizeof(*NumProcessors) + sizeof(*NumProcessors));
|
||||
RootState = (ROOT_VMX_STATE *) ((char *)NumProcessors + 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +141,39 @@ UINT32 PeSmiHandler(UINT32 CpuIndex)
|
|||
RootState = (ROOT_VMX_STATE *) ((char *)NumProcessors + 64);
|
||||
|
||||
GetRootVmxState(CpuIndex, &RootState[CpuIndex]);
|
||||
retvalue = 1;
|
||||
CpuReadySync(CpuIndex);
|
||||
|
||||
if (PeSmiControl.PeCpuIndex == (INT32)CpuIndex)
|
||||
{
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeWaitTimer, 1, 0);
|
||||
StopSwTimer();
|
||||
|
||||
// start the VM/PE
|
||||
PeVmData[PeType].StartMode = PEVM_PRESTART_SMI; // starting from SMI
|
||||
SetEndOfSmi(); // make sure that the timer SMI has been cleared
|
||||
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHTMR, PESMINULL);
|
||||
|
||||
for(CpuNum = 0; CpuNum < mHostContextCommon.CpuNum; CpuNum++)
|
||||
{
|
||||
PrintVmxState(CpuNum, &RootState[CpuNum]);
|
||||
}
|
||||
|
||||
if( mHostContextCommon.StmShutdown == 1)
|
||||
{
|
||||
// time to quit
|
||||
StmTeardown(CpuIndex);
|
||||
}
|
||||
|
||||
if(TimerSTS == 2)
|
||||
{
|
||||
// SMI has happened at the same time, so process it
|
||||
PeVmData[PeType].PeVmState = PE_VM_WAIT_START;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RunPermVM(CpuIndex);
|
||||
}
|
||||
|
||||
// we do not reset the state here as the VM/PE will be processing
|
||||
// when it competes it should end with a PeSmiState pf PESMIPNMI (waiting for NMI)
|
||||
|
@ -160,8 +182,8 @@ UINT32 PeSmiHandler(UINT32 CpuIndex)
|
|||
{
|
||||
if(CpuIndex == 0)
|
||||
{
|
||||
//PeSmiControl.PeSmiState = PESMINULL;
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMINULL); // one of these will work
|
||||
// One of these will work
|
||||
InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIHSMI, PESMINULL);
|
||||
}
|
||||
retvalue = 0;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,9 @@ int GetMultiProcessorState(UINT32 CpuIndex)
|
|||
{
|
||||
UINT32 PeType = PE_PERM;
|
||||
UINT64 * NumProcessors = (UINT64 *) PeVmData[PeType].SharedPageStm;
|
||||
ROOT_VMX_STATE * RootState; // = (ROOT_VMX_STATE *) (NumProcessors + sizeof(*NumProcessors));
|
||||
|
||||
// = (ROOT_VMX_STATE *) (NumProcessors + sizeof(*NumProcessors));
|
||||
ROOT_VMX_STATE * RootState;
|
||||
UINT32 CpuNum;
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
|
@ -72,10 +74,12 @@ int GetMultiProcessorState(UINT32 CpuIndex)
|
|||
}
|
||||
// first clear out the data structures and set the number of processors
|
||||
|
||||
RootState = (ROOT_VMX_STATE *) ((char *)NumProcessors + 64 );//sizeof(*NumProcessors) + sizeof(*NumProcessors));
|
||||
//sizeof(*NumProcessors) + sizeof(*NumProcessors));
|
||||
RootState = (ROOT_VMX_STATE *) ((char *)NumProcessors + 64 );
|
||||
*NumProcessors = mHostContextCommon.CpuNum; // number of CPUs
|
||||
|
||||
ZeroMem ((VOID *)(UINTN) RootState, sizeof(ROOT_VMX_STATE) * mHostContextCommon.CpuNum);
|
||||
ZeroMem ((VOID *)(UINTN) RootState,
|
||||
sizeof(ROOT_VMX_STATE) * mHostContextCommon.CpuNum);
|
||||
|
||||
// make sure that the VMCS offsets are setup
|
||||
|
||||
|
@ -83,9 +87,11 @@ int GetMultiProcessorState(UINT32 CpuIndex)
|
|||
|
||||
// send an SMI to the other processors
|
||||
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMINULL, PESMIPSMI) != PESMINULL) //&PeSmiControl.PeSmiState = 1;
|
||||
if(InterlockedCompareExchange32(&PeSmiControl.PeSmiState,
|
||||
PESMINULL,
|
||||
PESMIPSMI) != PESMINULL)
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld x - Aborting, SMI handler already there. PeSmiState %ld\n",
|
||||
CpuIndex,
|
||||
PeSmiControl.PeSmiState));
|
||||
|
@ -99,14 +105,10 @@ int GetMultiProcessorState(UINT32 CpuIndex)
|
|||
|
||||
// get the local processor state
|
||||
|
||||
//CpuReadySync(CpuIndex);
|
||||
GetRootVmxState(CpuIndex, &RootState[CpuIndex]);
|
||||
|
||||
// need to think about this --- without it this hangs, what in context of other processors
|
||||
//InterlockedCompareExchange32(&PeSmiControl.PeSmiState, PESMIPSMI, PESMINULL);//PeSmiControl.PeSmiState = 0; // all done - may need to sync processors in the case of
|
||||
// another SMI coming in
|
||||
|
||||
CpuReadySync(CpuIndex); // wait for everyone to finish the job - PeSmiHandler will set PeSmiState to 0
|
||||
CpuReadySync(CpuIndex); // wait for everyone to finish the job
|
||||
//- PeSmiHandler will set PeSmiState to 0
|
||||
// once everyone has synched up
|
||||
|
||||
for(CpuNum = 0; CpuNum < mHostContextCommon.CpuNum; CpuNum++)
|
||||
|
@ -114,7 +116,6 @@ int GetMultiProcessorState(UINT32 CpuIndex)
|
|||
PrintVmxState(CpuNum, &RootState[CpuNum]);
|
||||
}
|
||||
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld GetMultiProcessorState - Completed. PeSmiState: %ld\n",
|
||||
CpuIndex,
|
||||
|
@ -150,14 +151,17 @@ void GetRootVmxState(UINT32 CpuIndex, ROOT_VMX_STATE * RootState)
|
|||
RootState->Vmxon = mHostContextCommon.HostContextPerCpu[CpuIndex].Vmxon;
|
||||
//UINT32 ApicId = (UINT32) (get_apic_id() & 0xFF);
|
||||
RootState->LinkVMCS = VmRead64(VMCS_64_GUEST_VMCS_LINK_PTR_INDEX);
|
||||
RootState->ExecutiveVMCS = VmRead64(VMCS_64_CONTROL_EXECUTIVE_VMCS_PTR_INDEX); // get the executive VMCS
|
||||
|
||||
// DEBUG((EFI_D_ERROR, "%ld GetRootVmxState\n VMXON: 0x%016llx\n ExecutiveVMCS: 0x%016llx\n LinkVMCS: 0x%016llx\n",
|
||||
// CpuIndex,
|
||||
// RootState->Vmxon,
|
||||
// RootState->ExecutiveVMCS,
|
||||
// RootState->LinkVMCS));
|
||||
|
||||
// get the executive VMCS
|
||||
RootState->ExecutiveVMCS = VmRead64(VMCS_64_CONTROL_EXECUTIVE_VMCS_PTR_INDEX);
|
||||
|
||||
#if 0
|
||||
DEBUG((EFI_D_ERROR, "%ld GetRootVmxState\n VMXON: 0x%016llx\n ExecutiveVMCS: 0x%016llx\n LinkVMCS: 0x%016llx\n",
|
||||
CpuIndex,
|
||||
RootState->Vmxon,
|
||||
RootState->ExecutiveVMCS,
|
||||
RootState->LinkVMCS));
|
||||
#endif
|
||||
RootState->RootGuestCR0 = VmReadN(VMCS_N_GUEST_CR0_INDEX);
|
||||
RootState->RootGuestCR3 = VmReadN(VMCS_N_GUEST_CR3_INDEX);
|
||||
RootState->RootGuestCR4 = VmReadN(VMCS_N_GUEST_CR4_INDEX);
|
||||
|
@ -178,41 +182,36 @@ void GetRootVmxState(UINT32 CpuIndex, ROOT_VMX_STATE * RootState)
|
|||
|
||||
if(RootState->ExecutiveVMCS == RootState->Vmxon) // ref: section 34.15.4.7
|
||||
{
|
||||
// we are in root operation, so our VMCS of interest is in the VNCS-Link field
|
||||
// we are in root operation, so our VMCS of interest
|
||||
// is in the VNCS-Link field
|
||||
|
||||
if(RootState->LinkVMCS != 0xFFFFFFFFFFFFFFFF)
|
||||
{
|
||||
RootState->VmcsType = 1; // guest-VM being sericed by VMM
|
||||
HostRootVMCS = RootState->LinkVMCS;
|
||||
//HostRootVMCS = VmRead64(VMCS_64_GUEST_VMCS_LINK_PTR_INDEX);
|
||||
RootState->VmxState = VMX_STATE_ROOT;
|
||||
//DEBUG((EFI_D_DEBUG, "%ld GetRootVmxState (%d): execVMCS is vmxon: 0x%016llx using VMCS_LINK_POINTER\n",
|
||||
//CpuIndex, RootState->VmcsType, HostRootVMCS));
|
||||
}
|
||||
else
|
||||
{
|
||||
HostRootVMCS = RootState->ExecutiveVMCS;
|
||||
RootState->VmcsType = 2;
|
||||
//HostRootVMCS = VmRead64(VMCS_64_GUEST_VMCS_LINK_PTR_INDEX);
|
||||
RootState->VmxState = VMX_STATE_ROOT;
|
||||
//DEBUG((EFI_D_DEBUG, "%ld GetRootVmxState (%d): execVMCS is vmxon: But LinkVMCS is 0xFFFFFFFFFFFFFFF so no current Vmcs. Using Executive Vmcs: %llx\n",
|
||||
// CpuIndex, RootState->VmcsType, HostRootVMCS));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// in guest operation, so our VMCS of interest is in the executive-VMCS field
|
||||
// in guest operation, so our VMCS of interest
|
||||
// is in the executive-VMCS field
|
||||
|
||||
RootState->VmcsType = 3;
|
||||
HostRootVMCS = RootState->ExecutiveVMCS;
|
||||
RootState->VmxState = VMX_STATE_GUEST;
|
||||
//DEBUG((EFI_D_DEBUG, "%ld GetRootVmxState (%d): execVMCS is guest VMCS: 0x%016llx using Executive VMCS\n",
|
||||
//CpuIndex, RootState->VmcsType, HostRootVMCS));
|
||||
}
|
||||
|
||||
AsmVmClear(&(CurrentVMCSSave));
|
||||
AsmVmPtrStore(&CurrentVMCSSave);
|
||||
RootGuestRIP_M = *(UINT64 *)((UINTN)CurrentVMCSSave + (UINTN)VMCS_N_GUEST_RIP_OFFSET);
|
||||
RootGuestRIP_M = *(UINT64 *)((UINTN)CurrentVMCSSave +
|
||||
(UINTN)VMCS_N_GUEST_RIP_OFFSET);
|
||||
|
||||
VmcsFlushStart:
|
||||
FlushCount = 0;
|
||||
|
@ -222,8 +221,12 @@ VmcsFlushStart:
|
|||
{
|
||||
// got here because the in-memory copy of the VMCS is different than
|
||||
// what is in the processor - so we need to flush
|
||||
//DEBUG((EFI_D_DEBUG, "%ld - GetRootState: RootGuestRIPMemory: 0x%016llx, Location: 0x%016llx\n",
|
||||
//CpuIndex, RootGuestRIPMemory, ((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_RIP_OFFSET)));
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO, "%ld - GetRootState: RootGuestRIPMemory: 0x%016llx, Location: 0x%016llx\n",
|
||||
CpuIndex,
|
||||
RootGuestRIPMemory,
|
||||
((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_RIP_OFFSET)));
|
||||
#endif
|
||||
// first create a dummy VMCS
|
||||
VmxRevId = AsmReadMsr32(IA32_VMX_BASIC_MSR_INDEX);
|
||||
DummyVmcs[FlushCount] = (char *) AllocatePages(VmcsSizeInPages);
|
||||
|
@ -232,7 +235,7 @@ VmcsFlushStart:
|
|||
{
|
||||
// ran out of memory - release everything and start over
|
||||
// that way someone else hopefully gets a chance to complete
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld - GetRootState: ran out of memory - so free everything and restart - Flushcount: %d\n",
|
||||
CpuIndex,
|
||||
FlushCount));
|
||||
|
@ -248,11 +251,13 @@ VmcsFlushStart:
|
|||
|
||||
memcpy(DummyVmcs[FlushCount], &VmxRevId, 4);
|
||||
AsmVmPtrLoad((UINT64 *) &DummyVmcs[FlushCount]);
|
||||
RootGuestRIP_M = *(UINT64 *)((UINTN)CurrentVMCSSave + (UINTN)VMCS_N_GUEST_RIP_OFFSET); // try again
|
||||
RootGuestRIP_M = *(UINT64 *)((UINTN)CurrentVMCSSave +
|
||||
(UINTN)VMCS_N_GUEST_RIP_OFFSET); // try again
|
||||
FlushCount++;
|
||||
}
|
||||
|
||||
AsmVmPtrLoad(&CurrentVMCSSave); // in any case, reload this and free the dummies if necessary
|
||||
// in any case, reload this and free the dummies if necessary
|
||||
AsmVmPtrLoad(&CurrentVMCSSave);
|
||||
|
||||
if(FlushCount > 0)
|
||||
{
|
||||
|
@ -260,7 +265,6 @@ VmcsFlushStart:
|
|||
"%ld GetRootVmxState - Flush necessary to get VMCS in sync. Flushcount=%d\n",
|
||||
CpuIndex,
|
||||
FlushCount));
|
||||
//DEBUG((EFI_D_INFO, "%ld GetRootVmxState: after Flush: VMCS_N_GUEST_RIP_MEMORY: 0x%016llx (test) \n", CpuIndex, RootGuestRIPMemory));
|
||||
// release the buffers
|
||||
for(i = 0; i < FlushCount; i++)
|
||||
{
|
||||
|
@ -273,24 +277,35 @@ VmcsFlushStart:
|
|||
//AsmVmPtrLoad(&HostRootVMCS);
|
||||
|
||||
RootState->HostRootVMCS = HostRootVMCS;
|
||||
//DEBUG((EFI_D_DEBUG, "%ld - GetRootVmxState: HostRootVmcs 0x%016llx\n", CpuIndex, RootState->HostRootVMCS));
|
||||
|
||||
RootGuestCR0_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_CR0_OFFSET);
|
||||
RootGuestCR3_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_CR3_OFFSET);
|
||||
RootGuestCR4_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_CR4_OFFSET);
|
||||
RootGuestGDTRBase_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_GDTR_BASE_OFFSET);
|
||||
RootGuestGDTRLimit_M = (*(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_32_GUEST_GDTR_LIMIT_OFFSET)) & 0x00000000FFFFFFFF;
|
||||
RootGuestIDTRBase_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_IDTR_BASE_OFFSET);
|
||||
RootGuestIDTRLimit_M = (*(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_32_GUEST_LDTR_LIMIT_OFFSET)) & 0x00000000FFFFFFFF;
|
||||
RootGuestRSP_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_RSP_OFFSET);
|
||||
RootGuestRIP_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_RIP_OFFSET);
|
||||
RootContExecVmcs_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_64_CONTROL_EXECUTIVE_VMCS_PTR_OFFSET);
|
||||
RootContLinkVmcs_M = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_64_GUEST_VMCS_LINK_PTR_OFFSET);
|
||||
RootGuestCR0_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_GUEST_CR0_OFFSET);
|
||||
RootGuestCR3_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_GUEST_CR3_OFFSET);
|
||||
RootGuestCR4_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_GUEST_CR4_OFFSET);
|
||||
RootGuestGDTRBase_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_GUEST_GDTR_BASE_OFFSET);
|
||||
RootGuestGDTRLimit_M = (*(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_32_GUEST_GDTR_LIMIT_OFFSET)) & 0x00000000FFFFFFFF;
|
||||
RootGuestIDTRBase_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_GUEST_IDTR_BASE_OFFSET);
|
||||
RootGuestIDTRLimit_M = (*(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_32_GUEST_LDTR_LIMIT_OFFSET)) & 0x00000000FFFFFFFF;
|
||||
RootGuestRSP_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_GUEST_RSP_OFFSET);
|
||||
RootGuestRIP_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_GUEST_RIP_OFFSET);
|
||||
RootContExecVmcs_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_64_CONTROL_EXECUTIVE_VMCS_PTR_OFFSET);
|
||||
RootContLinkVmcs_M = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_64_GUEST_VMCS_LINK_PTR_OFFSET);
|
||||
|
||||
#ifdef VMCSDEBUGPRINT
|
||||
if(RootState->VmcsType !=2) // only want active Vmcs
|
||||
{
|
||||
DEBUG((EFI_D_DEBUG, "%ld GetRootVmxState (%d) HostRootVmcs 0x%016llx\n G_CR0 %llx\n G_CR3 %llx\n G_CR4 %llx\n G_GDTR %llx:%llx\n G_IDTR %llx:%llx\n G_RSP %llx\n G_RIP %llx\n",
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld GetRootVmxState (%d) HostRootVmcs 0x%016llx\n G_CR0 %llx\n G_CR3 %llx\n G_CR4 %llx\n G_GDTR %llx:%llx\n G_IDTR %llx:%llx\n G_RSP %llx\n G_RIP %llx\n",
|
||||
CpuIndex,
|
||||
RootState->VmcsType,
|
||||
RootState->HostRootVMCS,
|
||||
|
@ -304,7 +319,8 @@ VmcsFlushStart:
|
|||
RootState->RootGuestRSP,
|
||||
RootState->RootGuestRIP));
|
||||
|
||||
DEBUG((EFI_D_DEBIG, "%ld GetRootVmxState (%d) (control) HostRootVmcs 0x%016llx\n VMXON %llx\n ExecutiveVMCS %llx\n LinkVMCS %llx\n EPT %llx\n",
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld GetRootVmxState (%d) (control) HostRootVmcs 0x%016llx\n VMXON %llx\n ExecutiveVMCS %llx\n LinkVMCS %llx\n EPT %llx\n",
|
||||
CpuIndex,
|
||||
RootState->VmcsType,
|
||||
RootState->HostRootVMCS,
|
||||
|
@ -313,9 +329,9 @@ VmcsFlushStart:
|
|||
RootState->LinkVMCS,
|
||||
RootState->RootContEPT));
|
||||
|
||||
DEBUG((EFI_D_DEBUG, "%ld GetRootVmxState (%d) (memory) HostRootVmcs 0x%016llx\n G_CR0m %llx\n G_CR3m %llx\n G_CR4m %llx\n G_GDTRm %llx:%llx\n G_IDTRm %llx:%llx\n G_RSPm %llx\n G_RIPm %llx\n",
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld GetRootVmxState (%d) (memory) HostRootVmcs 0x%016llx\n G_CR0m %llx\n G_CR3m %llx\n G_CR4m %llx\n G_GDTRm %llx:%llx\n G_IDTRm %llx:%llx\n G_RSPm %llx\n G_RIPm %llx\n",
|
||||
CpuIndex,
|
||||
// "GetRootVmxState (memory)\n G_CR0m %llx\n G_CR3m %llx\n G_CR4m %llx\n G_GDTRm %llx:%llx\n G_IDTRm %llx:%llx\n G_RSPm %llx\n G_RIPm %llx\n C_ExecVMCSm %llx\n C_LinkVMCSm %llx\n",
|
||||
RootState->VmcsType,
|
||||
RootState->HostRootVMCS,
|
||||
RootGuestCR0_M,
|
||||
|
@ -328,7 +344,8 @@ VmcsFlushStart:
|
|||
RootGuestRSP_M,
|
||||
RootGuestRIP_M));
|
||||
|
||||
DEBUG((EFI_D_DEBUG, "%ld GetRootVmxState (%d) (memory) HostRootVmcs 0x%016llx\n C_ExecVMCSm %llx\n C_LinkVMCSm %llx\n",
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld GetRootVmxState (%d) (memory) HostRootVmcs 0x%016llx\n C_ExecVMCSm %llx\n C_LinkVMCSm %llx\n",
|
||||
CpuIndex,
|
||||
RootState->VmcsType,
|
||||
RootState->HostRootVMCS,
|
||||
|
@ -336,8 +353,6 @@ VmcsFlushStart:
|
|||
RootContLinkVmcs_M));
|
||||
}
|
||||
#endif
|
||||
//DEBUG((EFI_D_DEBUG, "%ld GetRootVmxState: VMCS_N_GUEST_RIP_MEMORY: 0x%016llx VMCS_N_GUEST_RIP: 0x%016llx, Location: 0x%016llx (test) \n",
|
||||
// CpuIndex, RootGuestRIP_M, RootState->RootGuestRIP, ((UINTN)HostRootVMCS + (UINTN)VMCS_N_GUEST_RIP_OFFSET)));
|
||||
|
||||
// need to save the root vmx host structures
|
||||
#ifdef ZERO
|
||||
|
@ -356,15 +371,23 @@ VmcsFlushStart:
|
|||
else
|
||||
#endif
|
||||
{
|
||||
RootState->RootHostCR0 = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_HOST_CR0_OFFSET);
|
||||
RootState->RootHostCR3 = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_HOST_CR3_OFFSET);
|
||||
RootState->RootHostCR4 = *(UINT64 *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_HOST_CR4_OFFSET);
|
||||
RootState->RootHostGDTRBase = *(UINTN *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_HOST_GDTR_BASE_OFFSET);
|
||||
RootState->RootHostIDTRBase = *(UINTN *)((UINTN)HostRootVMCS + (UINTN)VMCS_N_HOST_IDTR_BASE_OFFSET);
|
||||
RootState->RootHostCR0 = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_HOST_CR0_OFFSET);
|
||||
RootState->RootHostCR3 = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_HOST_CR3_OFFSET);
|
||||
RootState->RootHostCR4 = *(UINT64 *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_HOST_CR4_OFFSET);
|
||||
RootState->RootHostGDTRBase = *(UINTN *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_HOST_GDTR_BASE_OFFSET);
|
||||
RootState->RootHostIDTRBase = *(UINTN *)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_HOST_IDTR_BASE_OFFSET);
|
||||
|
||||
RootState->RootHostRSP = *(UINTN*)((UINTN)HostRootVMCS + (UINTN)VMCS_N_HOST_RSP_OFFSET);
|
||||
RootState->RootHostRIP = *(UINTN*)((UINTN)HostRootVMCS + (UINTN)VMCS_N_HOST_RIP_OFFSET);
|
||||
RootState->RootHostEPT = *(UINTN*)((UINTN)HostRootVMCS + (UINTN)VMCS_64_CONTROL_EPT_PTR_OFFSET);
|
||||
RootState->RootHostRSP = *(UINTN*)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_HOST_RSP_OFFSET);
|
||||
RootState->RootHostRIP = *(UINTN*)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_N_HOST_RIP_OFFSET);
|
||||
RootState->RootHostEPT = *(UINTN*)((UINTN)HostRootVMCS +
|
||||
(UINTN)VMCS_64_CONTROL_EPT_PTR_OFFSET);
|
||||
}
|
||||
// Indicate to the master that we are all done
|
||||
|
||||
|
@ -377,7 +400,8 @@ VmcsFlushStart:
|
|||
#ifdef VMCSDEBUGPRINT
|
||||
if(RootState->VmcsType != 2)
|
||||
{
|
||||
DEBUG((EFI_D_DEBUG, "%ld GetRootVmxState (%d) \n H_CR0 %llx\n H_CR3 %llx\n H_CR4 %llx\n H_GDTR %llx\n H_IDTR %llx\n H_RSP %llx\n H_RIP %llx\n H_EPT %llx\n",
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld GetRootVmxState (%d) \n H_CR0 %llx\n H_CR3 %llx\n H_CR4 %llx\n H_GDTR %llx\n H_IDTR %llx\n H_RSP %llx\n H_RIP %llx\n H_EPT %llx\n",
|
||||
CpuIndex,
|
||||
RootState->VmcsType,
|
||||
RootState->RootHostCR0,
|
||||
|
@ -422,17 +446,20 @@ void SetupGetRootVmxState()
|
|||
VMCS_N_GUEST_IDTR_BASE_OFFSET = GetVmcsOffset(VMCS_N_GUEST_IDTR_BASE_INDEX);
|
||||
VMCS_32_GUEST_LDTR_LIMIT_OFFSET = GetVmcsOffset(VMCS_32_GUEST_LDTR_LIMIT_INDEX);
|
||||
VMCS_N_GUEST_RSP_OFFSET = GetVmcsOffset(VMCS_N_GUEST_RSP_INDEX);
|
||||
VMCS_64_CONTROL_EXECUTIVE_VMCS_PTR_OFFSET = GetVmcsOffset(VMCS_64_CONTROL_EXECUTIVE_VMCS_PTR_INDEX);
|
||||
VMCS_64_GUEST_VMCS_LINK_PTR_OFFSET = GetVmcsOffset(VMCS_64_GUEST_VMCS_LINK_PTR_INDEX);
|
||||
VMCS_64_CONTROL_EXECUTIVE_VMCS_PTR_OFFSET =
|
||||
GetVmcsOffset(VMCS_64_CONTROL_EXECUTIVE_VMCS_PTR_INDEX);
|
||||
VMCS_64_GUEST_VMCS_LINK_PTR_OFFSET =
|
||||
GetVmcsOffset(VMCS_64_GUEST_VMCS_LINK_PTR_INDEX);
|
||||
// need to initialize the VMCS Offset table, if it has not already been done
|
||||
VMCS_OFFSET_READY = 1;
|
||||
}
|
||||
|
||||
void PrintVmxState(UINT32 CpuIndex, ROOT_VMX_STATE * RootState)
|
||||
{
|
||||
if(RootState->ExecutiveVMCS == RootState->Vmxon) // ref: section 34.15.4.7
|
||||
if(RootState->ExecutiveVMCS == RootState->Vmxon)// ref: section 34.15.4.7
|
||||
{
|
||||
// we are in root operation, so our VMCS of interest is in the VNCS-Link field
|
||||
// we are in root operation,
|
||||
//so our VMCS of interest is in the VNCS-Link field
|
||||
|
||||
if(RootState->LinkVMCS != 0xFFFFFFFFFFFFFFFF)
|
||||
{
|
||||
|
@ -453,7 +480,8 @@ void PrintVmxState(UINT32 CpuIndex, ROOT_VMX_STATE * RootState)
|
|||
}
|
||||
else
|
||||
{
|
||||
// in guest operation, so our VMCS of interest is in the executive-VMCS field
|
||||
// in guest operation,
|
||||
// so our VMCS of interest is in the executive-VMCS field
|
||||
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PrintVmxState (%d): execVMCS is guest VMCS: 0x%016llx using Executive VMCS\n",
|
||||
|
@ -489,7 +517,8 @@ void PrintVmxState(UINT32 CpuIndex, ROOT_VMX_STATE * RootState)
|
|||
RootState->LinkVMCS,
|
||||
RootState->RootContEPT));
|
||||
|
||||
DEBUG((EFI_D_INFO, "%ld PrintVmxState (%d) \n H_CR0 %llx\n H_CR3 %llx\n H_CR4 %llx\n H_GDTR %llx\n H_IDTR %llx\n H_RSP %llx\n H_RIP %llx\n H_EPT %llx\n",
|
||||
DEBUG((EFI_D_INFO,
|
||||
"%ld PrintVmxState (%d) \n H_CR0 %llx\n H_CR3 %llx\n H_CR4 %llx\n H_GDTR %llx\n H_IDTR %llx\n H_RSP %llx\n H_RIP %llx\n H_EPT %llx\n",
|
||||
CpuIndex,
|
||||
RootState->VmcsType,
|
||||
RootState->RootHostCR0,
|
||||
|
@ -503,4 +532,3 @@ void PrintVmxState(UINT32 CpuIndex, ROOT_VMX_STATE * RootState)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,8 +69,10 @@ VOID
|
|||
if(PeSmiControl.PeCpuIndex == ((INT32) Index))
|
||||
{
|
||||
PeType = mHostContextCommon.HostContextPerCpu[Index].NonSmiHandler;
|
||||
//PeType = mHostContextCommon.HostContextPerCpu[Index].GuestVmType;
|
||||
DEBUG((EFI_D_ERROR, "%ld RsmHandler - VmPe Detected - PeType: %ld PeVmState: %ld\n", Index, PeType, PeVmData[PeType].PeVmState));
|
||||
DEBUG((EFI_D_INFO, "%ld RsmHandler - VmPe Detected - PeType: %ld PeVmState: %ld\n",
|
||||
Index,
|
||||
PeType,
|
||||
PeVmData[PeType].PeVmState));
|
||||
|
||||
switch(PeVmData[PeType].PeVmState)
|
||||
{
|
||||
|
@ -81,13 +83,23 @@ VOID
|
|||
RestoreInterPeVm(Index, PeType);
|
||||
//should not return... will let the module handle the error processing
|
||||
|
||||
// this will return in the case where the VM/PE was being created and it was interrupted by a SMI that was detected
|
||||
// this will return in the case where the VM/PE was being created and
|
||||
// it was interrupted by a SMI that was detected
|
||||
// while doing the processor state gathering.
|
||||
// we will come out and let it return so that the SMI can get fired and
|
||||
// when the SMI handler is done will reattempt to regather the processor info
|
||||
DEBUG((EFI_D_ERROR, "%ld RsmHandler ERROR - Failed to restart PE/VM after SMI, PeType: %ld\n", Index, PeType));
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld RsmHandler ERROR - Failed to restart PE/VM after SMI, PeType: %ld\n",
|
||||
Index,
|
||||
PeType));
|
||||
break;
|
||||
}
|
||||
case PE_VM_WAIT_START:
|
||||
{
|
||||
RunPermVM(Index);
|
||||
DEBUG ((EFI_D_ERROR, "%ld RsmHandler - Unable to start Perm PE VM", Index));
|
||||
break;
|
||||
}
|
||||
case PE_VM_IDLE:
|
||||
case PE_VM_AVAIL:
|
||||
{
|
||||
|
@ -96,7 +108,9 @@ VOID
|
|||
}
|
||||
default:
|
||||
{
|
||||
DEBUG((EFI_D_ERROR, " %ld RsmHandler - data structure inconsistency - suspended PE/VM not found\n", Index));
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"%ld RsmHandler - data structure inconsistency - suspended PE/VM not found\n",
|
||||
Index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue