Exemplo n.º 1
0
/**
 * Signal a fatal wait error.
 *
 * @returns Fatal error code to be propagated up the call stack.
 * @param   pUVCpu              The user mode per CPU structure of the calling
 *                              EMT.
 * @param   pszFmt              The error format with a single %Rrc in it.
 * @param   rcFmt               The status code to format.
 */
static int vmR3FatalWaitError(PUVMCPU pUVCpu, const char *pszFmt, int rcFmt)
{
    /** @todo This is wrong ... raise a fatal error / guru meditation
     *        instead. */
    AssertLogRelMsgFailed((pszFmt, rcFmt));
    ASMAtomicUoWriteBool(&pUVCpu->pUVM->vm.s.fTerminateEMT, true);
    if (pUVCpu->pVM)
        VM_FF_SET(pUVCpu->pVM, VM_FF_CHECK_VM_STATE);
    return VERR_VM_FATAL_WAIT_ERROR;
}
/**
 * Insert pending notification
 *
 * @param   pVM             Pointer to the VM.
 * @param   pRec            Notification record to insert
 */
static void remNotifyHandlerInsert(PVM pVM, PREMHANDLERNOTIFICATION pRec)
{
    /*
     * Fetch a free record.
     */
    uint32_t                cFlushes = 0;
    uint32_t                idxFree;
    PREMHANDLERNOTIFICATION pFree;
    do
    {
        idxFree = ASMAtomicUoReadU32(&pVM->rem.s.idxFreeList);
        if (idxFree == UINT32_MAX)
        {
            do
            {
                cFlushes++;
                Assert(cFlushes != 128);
                AssertFatal(cFlushes < _1M);
                VMMRZCallRing3NoCpu(pVM, VMMCALLRING3_REM_REPLAY_HANDLER_NOTIFICATIONS, 0);
                idxFree = ASMAtomicUoReadU32(&pVM->rem.s.idxFreeList);
            } while (idxFree == UINT32_MAX);
        }
        pFree = &pVM->rem.s.aHandlerNotifications[idxFree];
    } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxFreeList, pFree->idxNext, idxFree));

    /*
     * Copy the record.
     */
    pFree->enmKind = pRec->enmKind;
    pFree->u = pRec->u;

    /*
     * Insert it into the pending list.
     */
    uint32_t idxNext;
    do
    {
        idxNext = ASMAtomicUoReadU32(&pVM->rem.s.idxPendingList);
        ASMAtomicWriteU32(&pFree->idxNext, idxNext);
        ASMCompilerBarrier();
    } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxPendingList, idxFree, idxNext));

    VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY);
}
Exemplo n.º 3
0
/**
 * Sets the VMM Debug Command variable.
 *
 * @returns Previous command.
 * @param   pVM     Pointer to the VM.
 * @param   enmCmd  The command.
 */
DECLINLINE(DBGFCMD) dbgfR3SetCmd(PVM pVM, DBGFCMD enmCmd)
{
    DBGFCMD rc;
    if (enmCmd == DBGFCMD_NO_COMMAND)
    {
        Log2(("DBGF: Setting command to %d (DBGFCMD_NO_COMMAND)\n", enmCmd));
        rc = (DBGFCMD)ASMAtomicXchgU32((uint32_t volatile *)(void *)&pVM->dbgf.s.enmVMMCmd, enmCmd);
        VM_FF_CLEAR(pVM, VM_FF_DBGF);
    }
    else
    {
        Log2(("DBGF: Setting command to %d\n", enmCmd));
        AssertMsg(pVM->dbgf.s.enmVMMCmd == DBGFCMD_NO_COMMAND, ("enmCmd=%d enmVMMCmd=%d\n", enmCmd, pVM->dbgf.s.enmVMMCmd));
        rc = (DBGFCMD)ASMAtomicXchgU32((uint32_t volatile *)(void *)&pVM->dbgf.s.enmVMMCmd, enmCmd);
        VM_FF_SET(pVM, VM_FF_DBGF);
        VMR3NotifyGlobalFFU(pVM->pUVM, 0 /* didn't notify REM */);
    }
    return rc;
}
Exemplo n.º 4
0
/**
 * Queue an item.
 * The item must have been obtained using PDMQueueAlloc(). Once the item
 * have been passed to this function it must not be touched!
 *
 * @param   pQueue      The queue handle.
 * @param   pItem       The item to insert.
 * @thread  Any thread.
 */
VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
{
    Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
    Assert(VALID_PTR(pItem));

#if 0 /* the paranoid android version: */
    void *pvNext;
    do
    {
        pvNext = ASMAtomicUoReadPtr((void * volatile *)&pQueue->CTX_SUFF(pPending));
        ASMAtomicUoWritePtr((void * volatile *)&pItem->CTX_SUFF(pNext), pvNext);
    } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pvNext));
#else
    PPDMQUEUEITEMCORE pNext;
    do
    {
        pNext = pQueue->CTX_SUFF(pPending);
        pItem->CTX_SUFF(pNext) = pNext;
    } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pNext));
#endif

    if (!pQueue->pTimer)
    {
        PVM pVM = pQueue->CTX_SUFF(pVM);
        Log2(("PDMQueueInsert: VM_FF_PDM_QUEUES %d -> 1\n", VM_FF_ISSET(pVM, VM_FF_PDM_QUEUES)));
        VM_FF_SET(pVM, VM_FF_PDM_QUEUES);
        ASMAtomicBitSet(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_PENDING_BIT);
#ifdef IN_RING3
# ifdef VBOX_WITH_REM
        REMR3NotifyQueuePending(pVM); /** @todo r=bird: we can remove REMR3NotifyQueuePending and let VMR3NotifyFF do the work. */
# endif
        VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
#endif
    }
    STAM_REL_COUNTER_INC(&pQueue->StatInsert);
    STAM_STATS({ ASMAtomicIncU32(&pQueue->cStatPending); });
Exemplo n.º 5
0
/**
 * Interface that PDM the helper asynchronous notification completed methods
 * uses for EMT0 when it is waiting inside VMR3AsyncPdmNotificationWaitU().
 *
 * @param   pUVM                Pointer to the user mode VM structure.
 */
VMMR3_INT_DECL(void) VMR3AsyncPdmNotificationWakeupU(PUVM pUVM)
{
    LogFlow(("VMR3AsyncPdmNotificationWakeupU:\n"));
    VM_FF_SET(pUVM->pVM, VM_FF_REQUEST); /* this will have to do for now. */
    g_aHaltMethods[pUVM->vm.s.iHaltMethod].pfnNotifyCpuFF(&pUVM->aCpus[0], 0 /*fFlags*/);
}