本文整理汇总了C++中VMMGetCpu函数的典型用法代码示例。如果您正苦于以下问题:C++ VMMGetCpu函数的具体用法?C++ VMMGetCpu怎么用?C++ VMMGetCpu使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了VMMGetCpu函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: VMMDECL
/**
* Records a invlpg instruction for replaying upon REM entry.
*
* @param pVM Pointer to the VM.
* @param GCPtrPage The
*/
VMMDECL(void) REMNotifyInvalidatePage(PVM pVM, RTGCPTR GCPtrPage)
{
/*
* Try take the REM lock and push the address onto the array.
*/
if ( pVM->rem.s.cInvalidatedPages < RT_ELEMENTS(pVM->rem.s.aGCPtrInvalidatedPages)
&& EMRemTryLock(pVM) == VINF_SUCCESS)
{
uint32_t iPage = pVM->rem.s.cInvalidatedPages;
if (iPage < RT_ELEMENTS(pVM->rem.s.aGCPtrInvalidatedPages))
{
ASMAtomicWriteU32(&pVM->rem.s.cInvalidatedPages, iPage + 1);
pVM->rem.s.aGCPtrInvalidatedPages[iPage] = GCPtrPage;
EMRemUnlock(pVM);
return;
}
CPUMSetChangedFlags(VMMGetCpu(pVM), CPUM_CHANGED_GLOBAL_TLB_FLUSH); /** @todo this array should be per-cpu technically speaking. */
ASMAtomicWriteU32(&pVM->rem.s.cInvalidatedPages, 0); /** @todo leave this alone? Optimize this code? */
EMRemUnlock(pVM);
}
else
{
/* Fallback: Simply tell the recompiler to flush its TLB. */
CPUMSetChangedFlags(VMMGetCpu(pVM), CPUM_CHANGED_GLOBAL_TLB_FLUSH);
ASMAtomicWriteU32(&pVM->rem.s.cInvalidatedPages, 0); /** @todo leave this alone?! Optimize this code? */
}
return;
}
示例2: DECLCALLBACK
/** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */
static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
PVM pVM = pDevIns->Internal.s.pVMR0;
pdmLock(pVM);
uint32_t uTagSrc;
if (iLevel & PDM_IRQ_LEVEL_HIGH)
{
pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
if (iLevel == PDM_IRQ_LEVEL_HIGH)
VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
else
VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
}
else
uTagSrc = pDevIns->Internal.s.uLastIrqTag;
bool fRc = pdmR0IsaSetIrq(pVM, iIrq, iLevel, uTagSrc);
if (iLevel == PDM_IRQ_LEVEL_LOW && fRc)
VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
pdmUnlock(pVM);
LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
}
示例3: DECLCALLBACK
/** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */
static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
PVM pVM = pDevIns->Internal.s.pVMR3;
pdmLock(pVM);
uint32_t uTagSrc;
if (iLevel & PDM_IRQ_LEVEL_HIGH)
{
pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
if (iLevel == PDM_IRQ_LEVEL_HIGH)
VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
else
VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
}
else
uTagSrc = pDevIns->Internal.s.uLastIrqTag;
PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
if (iLevel == PDM_IRQ_LEVEL_LOW)
VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
pdmUnlock(pVM);
return 0;
}
示例4: DECLCALLBACK
/**
* The global 1 halt method - VMR3Wait() worker.
*
* @returns VBox status code.
* @param pUVCpu Pointer to the user mode VMCPU structure.
*/
static DECLCALLBACK(int) vmR3HaltGlobal1Wait(PUVMCPU pUVCpu)
{
ASMAtomicWriteBool(&pUVCpu->vm.s.fWait, true);
PVM pVM = pUVCpu->pUVM->pVM;
PVMCPU pVCpu = VMMGetCpu(pVM);
Assert(pVCpu->idCpu == pUVCpu->idCpu);
int rc = VINF_SUCCESS;
for (;;)
{
/*
* Check Relevant FFs.
*/
if ( VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_SUSPENDED_MASK)
|| VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_EXTERNAL_SUSPENDED_MASK))
break;
/*
* Wait for a while. Someone will wake us up or interrupt the call if
* anything needs our attention.
*/
rc = SUPR3CallVMMR0Ex(pVM->pVMR0, pVCpu->idCpu, VMMR0_DO_GVMM_SCHED_HALT, RTTimeNanoTS() + 1000000000 /* +1s */, NULL);
if (rc == VERR_INTERRUPTED)
rc = VINF_SUCCESS;
else if (RT_FAILURE(rc))
{
rc = vmR3FatalWaitError(pUVCpu, "VMMR0_DO_GVMM_SCHED_HALT->%Rrc\n", rc);
break;
}
}
ASMAtomicUoWriteBool(&pUVCpu->vm.s.fWait, false);
return rc;
}
示例5: dbgfR3EventPrologue
/**
* The common event prologue code.
* It will set the 'stopped-in-hyper' flag, make sure someone is attached,
* and perhaps process any high priority pending actions (none yet).
*
* @returns VBox status.
* @param pVM Pointer to the VM.
* @param enmEvent The event to be sent.
*/
static int dbgfR3EventPrologue(PVM pVM, DBGFEVENTTYPE enmEvent)
{
/** @todo SMP */
PVMCPU pVCpu = VMMGetCpu(pVM);
/*
* Check if a debugger is attached.
*/
if ( !pVM->dbgf.s.fAttached
&& !dbgfR3WaitForAttach(pVM, enmEvent))
{
Log(("DBGFR3VMMEventSrc: enmEvent=%d - debugger not attached\n", enmEvent));
return VERR_DBGF_NOT_ATTACHED;
}
/*
* Sync back the state from the REM.
*/
dbgfR3EventSetStoppedInHyperFlag(pVM, enmEvent);
#ifdef VBOX_WITH_REM
if (!pVM->dbgf.s.fStoppedInHyper)
REMR3StateUpdate(pVM, pVCpu);
#endif
/*
* Look thru pending commands and finish those which make sense now.
*/
/** @todo Process/purge pending commands. */
//int rc = DBGFR3VMMForcedAction(pVM);
return VINF_SUCCESS;
}
示例6: VMMR3DECL
/**
* Forced action callback.
* The VMM will call this from it's main loop when VM_FF_DBGF is set.
*
* The function checks and executes pending commands from the debugger.
*
* @returns VINF_SUCCESS normally.
* @returns VERR_DBGF_RAISE_FATAL_ERROR to pretend a fatal error happened.
* @param pVM Pointer to the VM.
*/
VMMR3DECL(int) DBGFR3VMMForcedAction(PVM pVM)
{
int rc = VINF_SUCCESS;
if (VM_FF_TESTANDCLEAR(pVM, VM_FF_DBGF))
{
PVMCPU pVCpu = VMMGetCpu(pVM);
/*
* Commands?
*/
if (pVM->dbgf.s.enmVMMCmd != DBGFCMD_NO_COMMAND)
{
/** @todo stupid GDT/LDT sync hack. go away! */
SELMR3UpdateFromCPUM(pVM, pVCpu);
/*
* Process the command.
*/
bool fResumeExecution;
DBGFCMDDATA CmdData = pVM->dbgf.s.VMMCmdData;
DBGFCMD enmCmd = dbgfR3SetCmd(pVM, DBGFCMD_NO_COMMAND);
rc = dbgfR3VMMCmd(pVM, enmCmd, &CmdData, &fResumeExecution);
if (!fResumeExecution)
rc = dbgfR3VMMWait(pVM);
}
}
return rc;
}
示例7: VMMDECL
/**
* Sets the pending interrupt coming from ISA source or HPET.
*
* @returns VBox status code.
* @param pVM Pointer to the VM.
* @param u8Irq The IRQ line.
* @param u8Level The new level.
* @param uTagSrc The IRQ tag and source tracer ID.
*/
VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc)
{
pdmLock(pVM);
/** @todo put the IRQ13 code elsewhere to avoid this unnecessary bloat. */
if (!uTagSrc && (u8Level & PDM_IRQ_LEVEL_HIGH)) /* FPU IRQ */
{
if (u8Level == PDM_IRQ_LEVEL_HIGH)
VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), 0, 0);
else
VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), 0, 0);
}
int rc = VERR_PDM_NO_PIC_INSTANCE;
if (pVM->pdm.s.Pic.CTX_SUFF(pDevIns))
{
Assert(pVM->pdm.s.Pic.CTX_SUFF(pfnSetIrq));
pVM->pdm.s.Pic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns), u8Irq, u8Level, uTagSrc);
rc = VINF_SUCCESS;
}
if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns))
{
Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq));
/*
* Apply Interrupt Source Override rules.
* See ACPI 4.0 specification 5.2.12.4 and 5.2.12.5 for details on
* interrupt source override.
* Shortly, ISA IRQ0 is electically connected to pin 2 on IO-APIC, and some OSes,
* notably recent OS X rely upon this configuration.
* If changing, also update override rules in MADT and MPS.
*/
/* ISA IRQ0 routed to pin 2, all others ISA sources are identity mapped */
if (u8Irq == 0)
u8Irq = 2;
pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level, uTagSrc);
rc = VINF_SUCCESS;
}
if (!uTagSrc && u8Level == PDM_IRQ_LEVEL_LOW)
VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), 0, 0);
pdmUnlock(pVM);
return rc;
}
示例8: VMM_INT_DECL
/**
* Sets a checkpoint for syncing the state with the standby node
*
* @returns VBox status code.
*
* @param pVM The cross context VM structure.
* @param enmType Checkpoint type
*/
VMM_INT_DECL(int) FTMSetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType)
{
if (!pVM->fFaultTolerantMaster)
return VINF_SUCCESS;
#ifdef IN_RING3
return FTMR3SetCheckpoint(pVM, enmType);
#else
return VMMRZCallRing3(pVM, VMMGetCpu(pVM), VMMCALLRING3_FTM_SET_CHECKPOINT, enmType);
#endif
}
示例9: VMMDECL
/**
* Checks the caller is the owner of the critical section.
*
* @returns true if owner.
* @returns false if not owner.
* @param pCritSect The critical section.
*/
VMMDECL(bool) PDMCritSectIsOwner(PCPDMCRITSECT pCritSect)
{
#ifdef IN_RING3
return RTCritSectIsOwner(&pCritSect->s.Core);
#else
PVM pVM = pCritSect->s.CTX_SUFF(pVM); AssertPtr(pVM);
PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu);
if (pCritSect->s.Core.NativeThreadOwner != pVCpu->hNativeThread)
return false;
return (pCritSect->s.Core.fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK) == 0
|| pCritSect->s.Core.cNestings > 1;
#endif
}
示例10: DECL_FORCE_INLINE
/**
* Gets the ring-3 native thread handle of the calling thread.
*
* @returns native thread handle (ring-3).
* @param pCritSect The critical section. This is used in R0 and RC.
*/
DECL_FORCE_INLINE(RTNATIVETHREAD) pdmCritSectGetNativeSelf(PCPDMCRITSECT pCritSect)
{
#ifdef IN_RING3
NOREF(pCritSect);
RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
#else
AssertMsgReturn(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC, ("%RX32\n", pCritSect->s.Core.u32Magic),
NIL_RTNATIVETHREAD);
PVM pVM = pCritSect->s.CTX_SUFF(pVM); AssertPtr(pVM);
PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu);
RTNATIVETHREAD hNativeSelf = pVCpu->hNativeThread; Assert(hNativeSelf != NIL_RTNATIVETHREAD);
#endif
return hNativeSelf;
}
示例11: DECLINLINE
/**
* Internal worker for getting the GIP CPU array index for the calling CPU.
*
* @returns Index into SUPGLOBALINFOPAGE::aCPUs or UINT16_MAX.
* @param pGip The GIP.
*/
DECLINLINE(uint16_t) supGetGipCpuIndex(PSUPGLOBALINFOPAGE pGip)
{
uint16_t iGipCpu;
#ifdef IN_RING3
if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)
{
/* Storing the IDTR is normally very fast. */
uint16_t cbLim = ASMGetIdtrLimit();
uint16_t iCpuSet = cbLim - 256 * (ARCH_BITS == 64 ? 16 : 8);
iCpuSet &= RTCPUSET_MAX_CPUS - 1;
iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
}
else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)
{
/* RDTSCP gives us what need need and more. */
uint32_t iCpuSet;
ASMReadTscWithAux(&iCpuSet);
iCpuSet &= RTCPUSET_MAX_CPUS - 1;
iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
}
else
{
/* Get APIC ID via the slow CPUID instruction. */
uint8_t idApic = ASMGetApicId();
iGipCpu = pGip->aiCpuFromApicId[idApic];
}
#elif defined(IN_RING0)
/* Ring-0: Use use RTMpCpuId() (disables cli to avoid host OS assertions about unsafe CPU number usage). */
RTCCUINTREG uFlags = ASMIntDisableFlags();
int iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId());
if (RT_LIKELY((unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)))
iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
else
iGipCpu = UINT16_MAX;
ASMSetFlags(uFlags);
# elif defined(IN_RC)
/* Raw-mode context: We can get the host CPU set index via VMCPU. */
uint32_t iCpuSet = VMMGetCpu(&g_VM)->iHostCpuSet;
if (RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)))
iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
else
iGipCpu = UINT16_MAX;
#else
# error "IN_RING3, IN_RC or IN_RING0 must be defined!"
#endif
return iGipCpu;
}
示例12: VMMR3DECL
/**
* Query the state of a page in a shared module
*
* @returns VBox status code.
* @param pVM Pointer to the VM.
* @param GCPtrPage Page address.
* @param pfShared Shared status (out).
* @param pfPageFlags Page flags (out).
*/
VMMR3DECL(int) PGMR3SharedModuleGetPageState(PVM pVM, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *pfPageFlags)
{
/* Debug only API for the page fusion testcase. */
RTGCPHYS GCPhys;
uint64_t fFlags;
pgmLock(pVM);
int rc = PGMGstGetPage(VMMGetCpu(pVM), GCPtrPage, &fFlags, &GCPhys);
switch (rc)
{
case VINF_SUCCESS:
{
PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
if (pPage)
{
*pfShared = PGM_PAGE_IS_SHARED(pPage);
*pfPageFlags = fFlags;
}
else
rc = VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
break;
}
case VERR_PAGE_NOT_PRESENT:
case VERR_PAGE_TABLE_NOT_PRESENT:
case VERR_PAGE_MAP_LEVEL4_NOT_PRESENT:
case VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT:
*pfShared = false;
*pfPageFlags = 0;
rc = VINF_SUCCESS;
break;
default:
break;
}
pgmUnlock(pVM);
return rc;
}
示例13: VMMDECL
/**
* Get the timestamp frequency.
*
* @returns Number of ticks per second.
* @param pVM The cross context VM structure.
*/
VMMDECL(uint64_t) TMCpuTicksPerSecond(PVM pVM)
{
if ( pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET
&& g_pSUPGlobalInfoPage->u32Mode != SUPGIPMODE_INVARIANT_TSC)
{
#ifdef IN_RING3
uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);
#elif defined(IN_RING0)
uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, RTMpCpuIdToSetIndex(RTMpCpuId()));
#else
uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, VMMGetCpu(pVM)->iHostCpuSet);
#endif
if (RT_LIKELY(cTSCTicksPerSecond != ~(uint64_t)0))
return cTSCTicksPerSecond;
}
return pVM->tm.s.cTSCTicksPerSecond;
}
示例14: SUPDECL
/**
* The slow case for SUPReadTsc where we need to apply deltas.
*
* Must only be called when deltas are applicable, so please do not call it
* directly.
*
* @returns TSC with delta applied.
* @param pGip Pointer to the GIP.
*
* @remarks May be called with interrupts disabled in ring-0! This is why the
* ring-0 code doesn't attempt to figure the delta.
*
* @internal
*/
SUPDECL(uint64_t) SUPReadTscWithDelta(PSUPGLOBALINFOPAGE pGip)
{
uint64_t uTsc;
uint16_t iGipCpu;
AssertCompile(RT_IS_POWER_OF_TWO(RTCPUSET_MAX_CPUS));
AssertCompile(RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx) >= RTCPUSET_MAX_CPUS);
Assert(pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_PRACTICALLY_ZERO);
/*
* Read the TSC and get the corresponding aCPUs index.
*/
#ifdef IN_RING3
if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)
{
/* RDTSCP gives us all we need, no loops/cli. */
uint32_t iCpuSet;
uTsc = ASMReadTscWithAux(&iCpuSet);
iCpuSet &= RTCPUSET_MAX_CPUS - 1;
iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
}
else if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)
{
/* Storing the IDTR is normally very quick, but we need to loop. */
uint32_t cTries = 0;
for (;;)
{
uint16_t cbLim = ASMGetIdtrLimit();
uTsc = ASMReadTSC();
if (RT_LIKELY(ASMGetIdtrLimit() == cbLim))
{
uint16_t iCpuSet = cbLim - 256 * (ARCH_BITS == 64 ? 16 : 8);
iCpuSet &= RTCPUSET_MAX_CPUS - 1;
iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
break;
}
if (cTries >= 16)
{
iGipCpu = UINT16_MAX;
break;
}
cTries++;
}
}
else
{
/* Get APIC ID via the slow CPUID instruction, requires looping. */
uint32_t cTries = 0;
for (;;)
{
uint8_t idApic = ASMGetApicId();
uTsc = ASMReadTSC();
if (RT_LIKELY(ASMGetApicId() == idApic))
{
iGipCpu = pGip->aiCpuFromApicId[idApic];
break;
}
if (cTries >= 16)
{
iGipCpu = UINT16_MAX;
break;
}
cTries++;
}
}
#elif defined(IN_RING0)
/* Ring-0: Use use RTMpCpuId(), no loops. */
RTCCUINTREG uFlags = ASMIntDisableFlags();
int iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId());
if (RT_LIKELY((unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)))
iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
else
iGipCpu = UINT16_MAX;
uTsc = ASMReadTSC();
ASMSetFlags(uFlags);
# elif defined(IN_RC)
/* Raw-mode context: We can get the host CPU set index via VMCPU, no loops. */
RTCCUINTREG uFlags = ASMIntDisableFlags(); /* Are already disable, but play safe. */
uint32_t iCpuSet = VMMGetCpu(&g_VM)->iHostCpuSet;
if (RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)))
iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
else
iGipCpu = UINT16_MAX;
uTsc = ASMReadTSC();
ASMSetFlags(uFlags);
#else
//.........这里部分代码省略.........
示例15: dbgfR3VMMWait
/**
* Waits for the debugger to respond.
*
* @returns VBox status. (clearify)
* @param pVM Pointer to the VM.
*/
static int dbgfR3VMMWait(PVM pVM)
{
PVMCPU pVCpu = VMMGetCpu(pVM);
LogFlow(("dbgfR3VMMWait:\n"));
/** @todo stupid GDT/LDT sync hack. go away! */
SELMR3UpdateFromCPUM(pVM, pVCpu);
int rcRet = VINF_SUCCESS;
/*
* Waits for the debugger to reply (i.e. issue an command).
*/
for (;;)
{
/*
* Wait.
*/
uint32_t cPollHack = 1; /** @todo this interface is horrible now that we're using lots of VMR3ReqCall stuff all over DBGF. */
for (;;)
{
int rc;
if ( !VM_FF_ISPENDING(pVM, VM_FF_EMT_RENDEZVOUS | VM_FF_REQUEST)
&& !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_REQUEST))
{
rc = RTSemPingWait(&pVM->dbgf.s.PingPong, cPollHack);
if (RT_SUCCESS(rc))
break;
if (rc != VERR_TIMEOUT)
{
LogFlow(("dbgfR3VMMWait: returns %Rrc\n", rc));
return rc;
}
}
if (VM_FF_ISPENDING(pVM, VM_FF_EMT_RENDEZVOUS))
{
rc = VMMR3EmtRendezvousFF(pVM, pVCpu);
cPollHack = 1;
}
else if ( VM_FF_ISPENDING(pVM, VM_FF_REQUEST)
|| VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_REQUEST))
{
LogFlow(("dbgfR3VMMWait: Processes requests...\n"));
rc = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY, false /*fPriorityOnly*/);
if (rc == VINF_SUCCESS)
rc = VMR3ReqProcessU(pVM->pUVM, pVCpu->idCpu, false /*fPriorityOnly*/);
LogFlow(("dbgfR3VMMWait: VMR3ReqProcess -> %Rrc rcRet=%Rrc\n", rc, rcRet));
cPollHack = 1;
}
else
{
rc = VINF_SUCCESS;
if (cPollHack < 120)
cPollHack++;
}
if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
{
switch (rc)
{
case VINF_EM_DBG_BREAKPOINT:
case VINF_EM_DBG_STEPPED:
case VINF_EM_DBG_STEP:
case VINF_EM_DBG_STOP:
AssertMsgFailed(("rc=%Rrc\n", rc));
break;
/* return straight away */
case VINF_EM_TERMINATE:
case VINF_EM_OFF:
LogFlow(("dbgfR3VMMWait: returns %Rrc\n", rc));
return rc;
/* remember return code. */
default:
AssertReleaseMsgFailed(("rc=%Rrc is not in the switch!\n", rc));
case VINF_EM_RESET:
case VINF_EM_SUSPEND:
case VINF_EM_HALT:
case VINF_EM_RESUME:
case VINF_EM_RESCHEDULE:
case VINF_EM_RESCHEDULE_REM:
case VINF_EM_RESCHEDULE_RAW:
if (rc < rcRet || rcRet == VINF_SUCCESS)
rcRet = rc;
break;
}
}
else if (RT_FAILURE(rc))
{
LogFlow(("dbgfR3VMMWait: returns %Rrc\n", rc));
return rc;
}
//.........这里部分代码省略.........