예제 #1
0
파일: PDMQueue.cpp 프로젝트: ryenus/vbox
/**
 * Relocate the queues.
 *
 * @param   pVM             Pointer to the VM.
 * @param   offDelta        The relocation delta.
 */
void pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta)
{
    /*
     * Process the queues.
     */
    PUVM      pUVM       = pVM->pUVM;
    PPDMQUEUE pQueueNext = pUVM->pdm.s.pQueuesTimer;
    PPDMQUEUE pQueue     = pUVM->pdm.s.pQueuesForced;
    do
    {
        while (pQueue)
        {
            if (pQueue->pVMRC)
            {
                pQueue->pVMRC = pVM->pVMRC;

                /* Pending RC items. */
                if (pQueue->pPendingRC)
                {
                    pQueue->pPendingRC += offDelta;
                    PPDMQUEUEITEMCORE pCur = (PPDMQUEUEITEMCORE)MMHyperRCToR3(pVM, pQueue->pPendingRC);
                    while (pCur->pNextRC)
                    {
                        pCur->pNextRC += offDelta;
                        pCur = (PPDMQUEUEITEMCORE)MMHyperRCToR3(pVM, pCur->pNextRC);
                    }
                }

                /* The free items. */
                uint32_t i = pQueue->iFreeTail;
                while (i != pQueue->iFreeHead)
                {
                    pQueue->aFreeItems[i].pItemRC = MMHyperR3ToRC(pVM, pQueue->aFreeItems[i].pItemR3);
                    i = (i + 1) % (pQueue->cItems + PDMQUEUE_FREE_SLACK);
                }
            }

            /* next queue */
            pQueue = pQueue->pNext;
        }

        /* next queue list */
        pQueue = pQueueNext;
        pQueueNext = NULL;
    } while (pQueue);
}
예제 #2
0
파일: CSAMAll.cpp 프로젝트: bringhurst/vbox
/**
 * Mark a page as scanned/not scanned
 *
 * @note: we always mark it as scanned, even if we haven't completely done so
 *
 * @returns VBox status code.
 * @param   pVM         Pointer to the VM.
 * @param   pPage       GC page address (not necessarily aligned)
 * @param   fScanned    Mark as scanned or not scanned
 *
 */
VMM_INT_DECL(int) CSAMMarkPage(PVM pVM, RTRCUINTPTR pPage, bool fScanned)
{
    int pgdir, bit;
    uintptr_t page;

#ifdef LOG_ENABLED
    if (fScanned && !CSAMIsPageScanned(pVM, (RTRCPTR)pPage))
       Log(("CSAMMarkPage %RRv\n", pPage));
#endif

    if (!CSAMIsEnabled(pVM))
        return VINF_SUCCESS;
    Assert(!HMIsEnabled(pVM));

    page  = (uintptr_t)pPage;
    pgdir = page >> X86_PAGE_4M_SHIFT;
    bit   = (page & X86_PAGE_4M_OFFSET_MASK) >> X86_PAGE_4K_SHIFT;

    Assert(pgdir < CSAM_PGDIRBMP_CHUNKS);
    Assert(bit < PAGE_SIZE);

    if(!CTXSUFF(pVM->csam.s.pPDBitmap)[pgdir])
    {
        STAM_COUNTER_INC(&pVM->csam.s.StatBitmapAlloc);
        int rc = MMHyperAlloc(pVM, CSAM_PAGE_BITMAP_SIZE, 0, MM_TAG_CSAM, (void **)&pVM->csam.s.CTXSUFF(pPDBitmap)[pgdir]);
        if (RT_FAILURE(rc))
        {
            Log(("MMHyperAlloc failed with %Rrc\n", rc));
            return rc;
        }
#ifdef IN_RC
        pVM->csam.s.pPDHCBitmapGC[pgdir] = MMHyperRCToR3(pVM, (RCPTRTYPE(void*))pVM->csam.s.pPDBitmapGC[pgdir]);
        if (!pVM->csam.s.pPDHCBitmapGC[pgdir])
        {
            Log(("MMHyperHC2GC failed for %RRv\n", pVM->csam.s.pPDBitmapGC[pgdir]));
            return rc;
        }
#else
        pVM->csam.s.pPDGCBitmapHC[pgdir] = MMHyperR3ToRC(pVM, pVM->csam.s.pPDBitmapHC[pgdir]);
        if (!pVM->csam.s.pPDGCBitmapHC[pgdir])
        {
            Log(("MMHyperHC2GC failed for %RHv\n", pVM->csam.s.pPDBitmapHC[pgdir]));
            return rc;
        }
#endif
    }
    if(fScanned)
        ASMBitSet((void *)pVM->csam.s.CTXSUFF(pPDBitmap)[pgdir], bit);
    else
        ASMBitClear((void *)pVM->csam.s.CTXSUFF(pPDBitmap)[pgdir], bit);

    return VINF_SUCCESS;
}
예제 #3
0
파일: tstMicro.cpp 프로젝트: bayasist/vbox
/**
 * 'Allocate' selectors for 32-bit code/data in rings 0-3.
 *
 * 0060 - r0 code
 * 0068 - r0 data
 *
 * 1060 - r1 code
 * 1068 - r1 data
 *
 * 2060 - r2 code
 * 2068 - r2 data
 *
 * 3060 - r3 code
 * 3068 - r3 data
 *
 */
static void SetupSelectors(PVM pVM)
{
    /*
     * Find the GDT - This is a HACK :-)
     */
    RTRCPTR     RCPtr = CPUMGetHyperGDTR(VMMGetCpu0(pVM), NULL);
    PX86DESC    paGDTEs = (PX86DESC)MMHyperRCToR3(pVM, RCPtr);

    for (unsigned i = 0; i <= 3; i++)
    {
        RTSEL Sel = (i << 12) + 0x60;

        /* 32-bit code selector. */
        PX86DESC pGDTE = &paGDTEs[Sel >> X86_SEL_SHIFT];
        pGDTE->au32[0] = pGDTE->au32[1] = 0;
        pGDTE->Gen.u16LimitLow  = 0xffff;
        pGDTE->Gen.u4LimitHigh  = 0xf;
        pGDTE->Gen.u1Granularity= 1;
        pGDTE->Gen.u1Present    = 1;
        pGDTE->Gen.u2Dpl        = i;
        pGDTE->Gen.u1DefBig     = 1;
        pGDTE->Gen.u1DescType   = 1; /* !system */
        pGDTE->Gen.u4Type       = X86_SEL_TYPE_ER_ACC;

        /* 32-bit data selector. */
        pGDTE++;
        pGDTE->au32[0] = pGDTE->au32[1] = 0;
        pGDTE->Gen.u16LimitLow  = 0xffff;
        pGDTE->Gen.u4LimitHigh  = 0xf;
        pGDTE->Gen.u1Granularity= 1;
        pGDTE->Gen.u1Present    = 1;
        pGDTE->Gen.u2Dpl        = i;
        pGDTE->Gen.u1DefBig     = 1;
        pGDTE->Gen.u1DescType   = 1; /* !system */
        pGDTE->Gen.u4Type       = X86_SEL_TYPE_RW_ACC;
    }
}
예제 #4
0
파일: PDMQueue.cpp 프로젝트: ryenus/vbox
/**
 * Process pending items in one queue.
 *
 * @returns Success indicator.
 *          If false the item the consumer said "enough!".
 * @param   pQueue  The queue.
 */
static bool pdmR3QueueFlush(PPDMQUEUE pQueue)
{
    STAM_PROFILE_START(&pQueue->StatFlushPrf,p);

    /*
     * Get the lists.
     */
    PPDMQUEUEITEMCORE pItems   = ASMAtomicXchgPtrT(&pQueue->pPendingR3, NULL, PPDMQUEUEITEMCORE);
    RTRCPTR           pItemsRC = ASMAtomicXchgRCPtr(&pQueue->pPendingRC, NIL_RTRCPTR);
    RTR0PTR           pItemsR0 = ASMAtomicXchgR0Ptr(&pQueue->pPendingR0, NIL_RTR0PTR);

    AssertMsgReturn(   pItemsR0
                       || pItemsRC
                       || pItems,
                       ("Someone is racing us? This shouldn't happen!\n"),
                       true);

    /*
     * Reverse the list (it's inserted in LIFO order to avoid semaphores, remember).
     */
    PPDMQUEUEITEMCORE pCur = pItems;
    pItems = NULL;
    while (pCur)
    {
        PPDMQUEUEITEMCORE pInsert = pCur;
        pCur = pCur->pNextR3;
        pInsert->pNextR3 = pItems;
        pItems = pInsert;
    }

    /*
     * Do the same for any pending RC items.
     */
    while (pItemsRC)
    {
        PPDMQUEUEITEMCORE pInsert = (PPDMQUEUEITEMCORE)MMHyperRCToR3(pQueue->pVMR3, pItemsRC);
        pItemsRC = pInsert->pNextRC;
        pInsert->pNextRC = NIL_RTRCPTR;
        pInsert->pNextR3 = pItems;
        pItems = pInsert;
    }

    /*
     * Do the same for any pending R0 items.
     */
    while (pItemsR0)
    {
        PPDMQUEUEITEMCORE pInsert = (PPDMQUEUEITEMCORE)MMHyperR0ToR3(pQueue->pVMR3, pItemsR0);
        pItemsR0 = pInsert->pNextR0;
        pInsert->pNextR0 = NIL_RTR0PTR;
        pInsert->pNextR3 = pItems;
        pItems = pInsert;
    }

    /*
     * Feed the items to the consumer function.
     */
    Log2(("pdmR3QueueFlush: pQueue=%p enmType=%d pItems=%p\n", pQueue, pQueue->enmType, pItems));
    switch (pQueue->enmType)
    {
    case PDMQUEUETYPE_DEV:
        while (pItems)
        {
            if (!pQueue->u.Dev.pfnCallback(pQueue->u.Dev.pDevIns, pItems))
                break;
            pCur = pItems;
            pItems = pItems->pNextR3;
            pdmR3QueueFreeItem(pQueue, pCur);
        }
        break;

    case PDMQUEUETYPE_DRV:
        while (pItems)
        {
            if (!pQueue->u.Drv.pfnCallback(pQueue->u.Drv.pDrvIns, pItems))
                break;
            pCur = pItems;
            pItems = pItems->pNextR3;
            pdmR3QueueFreeItem(pQueue, pCur);
        }
        break;

    case PDMQUEUETYPE_INTERNAL:
        while (pItems)
        {
            if (!pQueue->u.Int.pfnCallback(pQueue->pVMR3, pItems))
                break;
            pCur = pItems;
            pItems = pItems->pNextR3;
            pdmR3QueueFreeItem(pQueue, pCur);
        }
        break;

    case PDMQUEUETYPE_EXTERNAL:
        while (pItems)
        {
            if (!pQueue->u.Ext.pfnCallback(pQueue->u.Ext.pvUser, pItems))
                break;
            pCur = pItems;
            pItems = pItems->pNextR3;
            pdmR3QueueFreeItem(pQueue, pCur);
        }
        break;

    default:
        AssertMsgFailed(("Invalid queue type %d\n", pQueue->enmType));
        break;
    }

    /*
     * Success?
     */
    if (pItems)
    {
        /*
         * Reverse the list.
         */
        pCur = pItems;
        pItems = NULL;
        while (pCur)
        {
            PPDMQUEUEITEMCORE pInsert = pCur;
            pCur = pInsert->pNextR3;
            pInsert->pNextR3 = pItems;
            pItems = pInsert;
        }

        /*
         * Insert the list at the tail of the pending list.
         */
        for (;;)
        {
            if (ASMAtomicCmpXchgPtr(&pQueue->pPendingR3, pItems, NULL))
                break;
            PPDMQUEUEITEMCORE pPending = ASMAtomicXchgPtrT(&pQueue->pPendingR3, NULL, PPDMQUEUEITEMCORE);
            if (pPending)
            {
                pCur = pPending;
                while (pCur->pNextR3)
                    pCur = pCur->pNextR3;
                pCur->pNextR3 = pItems;
                pItems = pPending;
            }
        }

        STAM_REL_COUNTER_INC(&pQueue->StatFlushLeftovers);
        STAM_PROFILE_STOP(&pQueue->StatFlushPrf,p);
        return false;
    }

    STAM_PROFILE_STOP(&pQueue->StatFlushPrf,p);
    return true;
}