/**
 * Allocates physical memory which satisfy the given constraints.
 *
 * @param   uPhysHi        The upper physical address limit (inclusive).
 * @param   puPhys         Where to store the physical address of the allocated
 *                         memory. Optional, can be NULL.
 * @param   cb             Size of allocation.
 * @param   uAlignment     Alignment.
 * @param   fContig        Whether the memory must be physically contiguous or
 *                         not.
 *
 * @returns Virtual address of allocated memory block or NULL if allocation
 *        failed.
 */
DECLHIDDEN(void *) rtR0SolMemAlloc(uint64_t uPhysHi, uint64_t *puPhys, size_t cb, uint64_t uAlignment, bool fContig)
{
    if ((cb & PAGEOFFSET) != 0)
        return NULL;

    size_t cPages = (cb + PAGESIZE - 1) >> PAGESHIFT;
    if (!cPages)
        return NULL;

    ddi_dma_attr_t DmaAttr = s_rtR0SolDmaAttr;
    DmaAttr.dma_attr_addr_hi    = uPhysHi;
    DmaAttr.dma_attr_align      = uAlignment;
    if (!fContig)
        DmaAttr.dma_attr_sgllen = cPages > INT_MAX ? INT_MAX - 1 : cPages;
    else
        AssertRelease(DmaAttr.dma_attr_sgllen == 1);

    void *pvMem = contig_alloc(cb, &DmaAttr, PAGESIZE, 1 /* can sleep */);
    if (!pvMem)
    {
        LogRel(("rtR0SolMemAlloc failed. cb=%u Align=%u fContig=%d\n", (unsigned)cb, (unsigned)uAlignment, fContig));
        return NULL;
    }

    pfn_t PageFrameNum = hat_getpfnum(kas.a_hat, (caddr_t)pvMem);
    AssertRelease(PageFrameNum != PFN_INVALID);
    if (puPhys)
        *puPhys = (uint64_t)PageFrameNum << PAGESHIFT;

    return pvMem;
}
/**
 * Flushes the physical handler notifications if the queue is almost full.
 *
 * This is for avoiding trouble in RC when changing CR3.
 *
 * @param   pVM         Pointer to the VM.
 * @param   pVCpu       Pointer to the VMCPU of the calling EMT.
 */
VMMDECL(void) REMNotifyHandlerPhysicalFlushIfAlmostFull(PVM pVM, PVMCPU pVCpu)
{
    Assert(pVM->cCpus == 1); NOREF(pVCpu);

    /*
     * Less than 48 items means we should flush.
     */
    uint32_t cFree = 0;
    for (uint32_t idx = pVM->rem.s.idxFreeList;
         idx != UINT32_MAX;
         idx = pVM->rem.s.aHandlerNotifications[idx].idxNext)
    {
        Assert(idx < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications));
        if (++cFree >= 48)
            return;
    }
    AssertRelease(VM_FF_IS_SET(pVM, VM_FF_REM_HANDLER_NOTIFY));
    AssertRelease(pVM->rem.s.idxPendingList != UINT32_MAX);

    /* Ok, we gotta flush them. */
    VMMRZCallRing3NoCpu(pVM, VMMCALLRING3_REM_REPLAY_HANDLER_NOTIFICATIONS, 0);

    AssertRelease(pVM->rem.s.idxPendingList == UINT32_MAX);
    AssertRelease(pVM->rem.s.idxFreeList != UINT32_MAX);
}
Beispiel #3
0
/**
 * Initializes the 64-bit IDT for 64-bit guest on 32-bit host switchers.
 *
 * This is only used as a debugging aid when we cannot find out why something
 * goes haywire in the intermediate context.
 *
 * @param   pVM        The cross context VM structure.
 * @param   pSwitcher   The switcher descriptor.
 * @param   pbDst       Where the switcher code was just copied.
 * @param   HCPhysDst   The host physical address corresponding to @a pbDst.
 */
static void vmmR3Switcher32On64IdtInit(PVM pVM, PVMMSWITCHERDEF pSwitcher, uint8_t *pbDst, RTHCPHYS HCPhysDst)
{
    AssertRelease(pSwitcher->offGCCode > 0 && pSwitcher->offGCCode < pSwitcher->cbCode);
    AssertRelease(pSwitcher->cbCode < _64K);
    RTSEL uCs64 = SELMGetHyperCS64(pVM);

    PX86DESC64GATE paIdt = (PX86DESC64GATE)(pbDst + pSwitcher->offGCCode);
    for (uint32_t i = 0 ; i < 256; i++)
    {
        AssertRelease(((uint64_t *)&paIdt[i])[0] < pSwitcher->cbCode);
        AssertRelease(((uint64_t *)&paIdt[i])[1] == 0);
        uint64_t uHandler = HCPhysDst + paIdt[i].u16OffsetLow;
        paIdt[i].u16OffsetLow   = (uint16_t)uHandler;
        paIdt[i].u16Sel         = uCs64;
        paIdt[i].u3IST          = 0;
        paIdt[i].u5Reserved     = 0;
        paIdt[i].u4Type         = AMD64_SEL_TYPE_SYS_INT_GATE;
        paIdt[i].u1DescType     = 0 /* system */;
        paIdt[i].u2Dpl          = 3;
        paIdt[i].u1Present      = 1;
        paIdt[i].u16OffsetHigh  = (uint16_t)(uHandler >> 16);
        paIdt[i].u32Reserved    = (uint32_t)(uHandler >> 32);
    }

    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
    {
        uint64_t uIdtr = HCPhysDst + pSwitcher->offGCCode; AssertRelease(uIdtr < UINT32_MAX);
        CPUMSetHyperIDTR(&pVM->aCpus[iCpu], uIdtr, 16*256 + iCpu);
    }
}
Beispiel #4
0
/**
 * Initializes the tracing.
 *
 * @returns VBox status code
 * @param   pVM         The cross context VM structure.
 * @param   cbEntry     The trace entry size.
 * @param   cEntries    The number of entries.
 */
static int dbgfR3TraceEnable(PVM pVM, uint32_t cbEntry, uint32_t cEntries)
{
    /*
     * Don't enable it twice.
     */
    if (pVM->hTraceBufR3 != NIL_RTTRACEBUF)
        return VERR_ALREADY_EXISTS;

    /*
     * Resolve default parameter values.
     */
    int rc;
    if (!cbEntry)
    {
        rc = CFGMR3QueryU32Def(CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"), "TraceBufEntrySize", &cbEntry, 128);
        AssertRCReturn(rc, rc);
    }
    if (!cEntries)
    {
        rc = CFGMR3QueryU32Def(CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"), "TraceBufEntries", &cEntries, 4096);
        AssertRCReturn(rc, rc);
    }

    /*
     * Figure the required size.
     */
    RTTRACEBUF  hTraceBuf;
    size_t      cbBlock = 0;
    rc = RTTraceBufCarve(&hTraceBuf, cEntries, cbEntry, 0 /*fFlags*/, NULL, &cbBlock);
    if (rc != VERR_BUFFER_OVERFLOW)
    {
        AssertReturn(!RT_SUCCESS_NP(rc), VERR_IPE_UNEXPECTED_INFO_STATUS);
        return rc;
    }

    /*
     * Allocate a hyper heap block and carve a trace buffer out of it.
     *
     * Note! We ASSUME that the returned trace buffer handle has the same value
     *       as the heap block.
     */
    cbBlock = RT_ALIGN_Z(cbBlock, PAGE_SIZE);
    void *pvBlock;
    rc = MMR3HyperAllocOnceNoRel(pVM, cbBlock, PAGE_SIZE, MM_TAG_DBGF, &pvBlock);
    if (RT_FAILURE(rc))
        return rc;

    rc = RTTraceBufCarve(&hTraceBuf, cEntries, cbEntry, 0 /*fFlags*/, pvBlock, &cbBlock);
    AssertRCReturn(rc, rc);
    AssertRelease(hTraceBuf == (RTTRACEBUF)pvBlock);
    AssertRelease((void *)hTraceBuf == pvBlock);

    pVM->hTraceBufR3 = hTraceBuf;
    pVM->hTraceBufR0 = MMHyperCCToR0(pVM, hTraceBuf);
    pVM->hTraceBufRC = MMHyperCCToRC(pVM, hTraceBuf);
    return VINF_SUCCESS;
}
Beispiel #5
0
/**
 * Gets the HC pointer to the dummy page.
 *
 * The dummy page is used as a place holder to prevent potential bugs
 * from doing really bad things to the system.
 *
 * @returns Pointer to the dummy page.
 * @param   pVM         The cross context VM structure.
 * @thread  The Emulation Thread.
 */
VMMR3DECL(void *) MMR3PageDummyHCPtr(PVM pVM)
{
    VM_ASSERT_EMT(pVM);
    if (!pVM->mm.s.pvDummyPage)
    {
        pVM->mm.s.pvDummyPage = mmR3PagePoolAlloc(pVM->mm.s.pPagePoolR3);
        AssertRelease(pVM->mm.s.pvDummyPage);
        pVM->mm.s.HCPhysDummyPage = mmPagePoolPtr2Phys(pVM->mm.s.pPagePoolR3, pVM->mm.s.pvDummyPage);
        AssertRelease(!(pVM->mm.s.HCPhysDummyPage & ~X86_PTE_PAE_PG_MASK));
    }
    return pVM->mm.s.pvDummyPage;
}
Beispiel #6
0
DECLEXPORT(EGLSurface) eglCreatePixmapSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativePixmapType hPixmap,
                                              const EGLint *paAttributes)
{
    Display *pDisplay = (Display *)hDisplay;
    GLXPixmap hGLXPixmap;

    if (!VALID_PTR(hDisplay))
    {
        setEGLError(EGL_NOT_INITIALIZED);
        return EGL_NO_SURFACE;
    }
    if (paAttributes != NULL)  /* Sanity test only. */
        if (*paAttributes != EGL_NONE)
        {
            if (*paAttributes == EGL_VG_COLORSPACE || *paAttributes == EGL_VG_ALPHA_FORMAT)
            {
                setEGLError(EGL_BAD_MATCH);
                return EGL_NO_SURFACE;
            }
            else
            {
                setEGLError(EGL_BAD_ATTRIBUTE);
                return EGL_NO_SURFACE;
            }
        }
    hGLXPixmap = glXCreatePixmap(pDisplay, (GLXFBConfig)config, (Pixmap)hPixmap, NULL);
    if (hGLXPixmap == None)
    {
        setEGLError(EGL_BAD_MATCH);
        return EGL_NO_SURFACE;
    }
    AssertRelease(hGLXPixmap < VBEGL_WINDOW_SURFACE);  /* Greater than the maximum XID. */
    clearEGLError();
    return (EGLSurface)(hGLXPixmap | VBEGL_PIXMAP_SURFACE);
}
Beispiel #7
0
DECLEXPORT(EGLSurface) eglCreateWindowSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativeWindowType hWindow,
                                              const EGLint *paAttributes)
{
    Display *pDisplay = (Display *)hDisplay;
    GLXWindow hGLXWindow;

    if (!VALID_PTR(hDisplay))
    {
        setEGLError(EGL_NOT_INITIALIZED);
        return EGL_NO_SURFACE;
    }
    if (paAttributes != NULL)  /* Sanity test only. */
        while (*paAttributes != EGL_NONE)
        {
            if (*paAttributes != EGL_RENDER_BUFFER)
            {
                setEGLError(EGL_BAD_MATCH);
                return EGL_NO_SURFACE;
            }
            paAttributes += 2;
        }
    hGLXWindow = glXCreateWindow(pDisplay, (GLXFBConfig)config, (Window)hWindow, NULL);
    if (hGLXWindow == None)
    {
        setEGLError(EGL_BAD_ALLOC);
        return EGL_NO_SURFACE;
    }
    AssertRelease(hGLXWindow < VBEGL_WINDOW_SURFACE);  /* Greater than the maximum XID. */
    clearEGLError();
    return (EGLSurface)(hGLXWindow | VBEGL_WINDOW_SURFACE);
}
RTCString &RTCString::appendCodePoint(RTUNICP uc)
{
    /*
     * Single byte encoding.
     */
    if (uc < 0x80)
        return RTCString::append((char)uc);

    /*
     * Multibyte encoding.
     * Assume max encoding length when resizing the string, that's simpler.
     */
    AssertReturn(uc <= UINT32_C(0x7fffffff), *this);

    if (m_cch + 6 >= m_cbAllocated)
    {
        reserve(RT_ALIGN_Z(m_cch + 6 + 1, IPRT_MINISTRING_APPEND_ALIGNMENT));
        // calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
#ifndef RT_EXCEPTIONS_ENABLED
        AssertRelease(capacity() > m_cch + 6);
#endif
    }

    char *pszNext = RTStrPutCp(&m_psz[m_cch], uc);
    m_cch = pszNext - m_psz;
    *pszNext = '\0';

    return *this;
}
Beispiel #9
0
/**
 * Notification wrapper that updates CPU states and invokes our notification
 * callbacks.
 *
 * @param idCpu             The CPU Id.
 * @param pvUser1           Pointer to the notifier_block (unused).
 * @param pvUser2           The notification event.
 * @remarks This can be invoked in interrupt context.
 */
static DECLCALLBACK(void) rtMpNotificationLinuxOnCurrentCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
{
    unsigned long ulNativeEvent = *(unsigned long *)pvUser2;
    NOREF(pvUser1);

    AssertRelease(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
    AssertReleaseMsg(idCpu == RTMpCpuId(),  /* ASSUMES iCpu == RTCPUID */
                     ("idCpu=%u RTMpCpuId=%d ApicId=%d\n", idCpu, RTMpCpuId(), ASMGetApicId() ));

    switch (ulNativeEvent)
    {
# ifdef CPU_DOWN_FAILED
        case CPU_DOWN_FAILED:
#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_FAILED_FROZEN)
        case CPU_DOWN_FAILED_FROZEN:
#  endif
# endif
        case CPU_ONLINE:
# if defined(CPU_TASKS_FROZEN) && defined(CPU_ONLINE_FROZEN)
        case CPU_ONLINE_FROZEN:
# endif
            rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, idCpu);
            break;

# ifdef CPU_DOWN_PREPARE
        case CPU_DOWN_PREPARE:
#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_PREPARE_FROZEN)
        case CPU_DOWN_PREPARE_FROZEN:
#  endif
            rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, idCpu);
            break;
# endif
    }
}
void hgcmObjDeleteHandle (uint32_t handle)
{
    int rc = VINF_SUCCESS;

    LogFlow(("MAIN::hgcmObjDeleteHandle: handle 0x%08X\n", handle));

    if (handle)
    {
        rc = hgcmObjEnter ();

        if (RT_SUCCESS(rc))
        {
            ObjectAVLCore *pCore = (ObjectAVLCore *)RTAvlULRemove (&g_pTree, handle);

            if (pCore)
            {
                AssertRelease(pCore->pSelf);

                pCore->pSelf->Dereference ();
            }

            hgcmObjLeave ();
        }
        else
        {
            AssertReleaseMsgFailed (("Failed to acquire object pool semaphore, rc = %Rrc", rc));
        }
    }

    LogFlow(("MAIN::hgcmObjDeleteHandle: rc = %Rrc, return void\n", rc));

    return;
}
/**
 * Insert a block from the tree.
 */
DECLINLINE(void) rtmemBlockInsert(PRTMEMBLOCK pBlock, void *pv)
{
    pBlock->Core.Key = pv;
    rtmemBlockLock();
    bool fRc = RTAvlPVInsert(&g_BlocksTree, &pBlock->Core);
    rtmemBlockUnlock();
    AssertRelease(fRc);
}
Beispiel #12
0
/**
 * Relocates the 64-bit IDT for 64-bit guest on 32-bit host switchers.
 *
 * @param   pVM        The cross context VM structure.
 * @param   pSwitcher   The switcher descriptor.
 * @param   pbDst       Where the switcher code was just copied.
 * @param   HCPhysDst   The host physical address corresponding to @a pbDst.
 */
static void vmmR3Switcher32On64IdtRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, uint8_t *pbDst, RTHCPHYS HCPhysDst)
{
    AssertRelease(pSwitcher->offGCCode > 0 && pSwitcher->offGCCode < pSwitcher->cbCode && pSwitcher->cbCode < _64K);

    /* The intermediate context doesn't move, but the CS may. */
    RTSEL uCs64 = SELMGetHyperCS64(pVM);
    PX86DESC64GATE paIdt = (PX86DESC64GATE)(pbDst + pSwitcher->offGCCode);
    for (uint32_t i = 0 ; i < 256; i++)
        paIdt[i].u16Sel = uCs64;

    /* Just in case... */
    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
    {
        uint64_t uIdtr = HCPhysDst + pSwitcher->offGCCode; AssertRelease(uIdtr < UINT32_MAX);
        CPUMSetHyperIDTR(&pVM->aCpus[iCpu], uIdtr, 16*256 + iCpu);
    }
}
Beispiel #13
0
bool crVBoxHGSMIInit(CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu)
{
    /* static */ int bHasHGSMI = -1; /* do it for all connections */
    (void) mtu;

    if (bHasHGSMI < 0)
    {
        int rc;
        VBOXCRHGSMI_CALLBACKS Callbacks;
        Callbacks.pfnClientCreate = _crVBoxHGSMIClientCreate;
        Callbacks.pfnClientDestroy = _crVBoxHGSMIClientDestroy;
        rc = VBoxCrHgsmiInit(&Callbacks);
        AssertRC(rc);
        if (RT_SUCCESS(rc))
            bHasHGSMI = 1;
        else
            bHasHGSMI = 0;
    }

    Assert(bHasHGSMI);

    if (!bHasHGSMI)
    {
#ifdef DEBUG_misha
        AssertRelease(0);
#endif
        return false;
    }

    g_crvboxhgsmi.recv_list = rfl;
    g_crvboxhgsmi.close_list = cfl;
    if (g_crvboxhgsmi.initialized)
    {
        return true;
    }

    g_crvboxhgsmi.initialized = 1;

    g_crvboxhgsmi.num_conns = 0;
    g_crvboxhgsmi.conns     = NULL;
    g_crvboxhgsmi.mempool = crBufferPoolInit(16);

    /* Can't open VBox guest driver here, because it gets called for host side as well */
    /*@todo as we have 2 dll versions, can do it now.*/

#ifdef RT_OS_WINDOWS
    g_crvboxhgsmi.hGuestDrv = INVALID_HANDLE_VALUE;
#else
    g_crvboxhgsmi.iGuestDrv = INVALID_HANDLE_VALUE;
#endif

#ifdef CHROMIUM_THREADSAFE
    crInitMutex(&g_crvboxhgsmi.mutex);
    crInitMutex(&g_crvboxhgsmi.recvmutex);
#endif

    return true;
}
RTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock)
{
#if 1
    if (RT_UNLIKELY(!(Spinlock->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)))
        RTAssertMsg2("RTSpinlockReleaseNoInts: %p (magic=%#x)\n", Spinlock, Spinlock->u32Magic);
#else
    AssertRelease(Spinlock->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE);
#endif
    RTSpinlockRelease(Spinlock);
}
static void fillTestShflString(struct TESTSHFLSTRING *pDest,
                               const char *pcszSource)
{
    AssertRelease(  strlen(pcszSource) * 2 + 2
                  < sizeof(*pDest) - RT_UOFFSETOF(SHFLSTRING, String));
    pDest->string.u16Length = (uint16_t)(strlen(pcszSource) * sizeof(RTUTF16));
    pDest->string.u16Size   = pDest->string.u16Length + sizeof(RTUTF16);
    for (unsigned i = 0; i <= pDest->string.u16Length; ++i)
        pDest->string.String.ucs2[i] = (uint16_t)pcszSource[i];
}
void hgcmObjDereference (HGCMObject *pObject)
{
    LogFlow(("MAIN::hgcmObjDereference: pObject %p\n", pObject));

    AssertRelease(pObject);

    pObject->Dereference ();

    LogFlow(("MAIN::hgcmObjDereference: return\n"));
}
Beispiel #17
0
/**
 * Handle display resize event.
 *
 * @returns COM status code
 * @param w New display width
 * @param h New display height
 */
int Display::handleDisplayResize (int w, int h)
{
    LogFlow(("Display::handleDisplayResize(): w=%d, h=%d\n", w, h));

    // if there is no Framebuffer, this call is not interesting
    if (mFramebuffer == NULL)
        return VINF_SUCCESS;

    /* Atomically set the resize status before calling the framebuffer. The new InProgress status will
     * disable access to the VGA device by the EMT thread.
     */
    bool f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_InProgress, ResizeStatus_Void);
    AssertRelease(f);NOREF(f);

    // callback into the Framebuffer to notify it
    BOOL finished;

    mFramebuffer->Lock();

    mFramebuffer->RequestResize(w, h, &finished);

    if (!finished)
    {
        LogFlow(("Display::handleDisplayResize: external framebuffer wants us to wait!\n"));

        /* Note: The previously obtained framebuffer lock must be preserved.
         *       The EMT keeps the framebuffer lock until the resize process completes.
         */

        return VINF_VGA_RESIZE_IN_PROGRESS;
    }

    /* Set the status so the 'handleResizeCompleted' would work.  */
    f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress);
    AssertRelease(f);NOREF(f);

    /* The method also unlocks the framebuffer. */
    handleResizeCompletedEMT();

    return VINF_SUCCESS;
}
Beispiel #18
0
/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
{
    PDMDEV_ASSERT_DEVINS(pDevIns);
    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    PCPDMHPETHLPR0 pR0Helpers = NIL_RTR0PTR;
    int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
    AssertReleaseRC(rc);
    AssertRelease(pR0Helpers);
    LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
             pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
    return pR0Helpers;
}
Beispiel #19
0
/** @interface_method_impl{PDMHPETHLPR3,pfnGetRCHelpers} */
static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
{
    PDMDEV_ASSERT_DEVINS(pDevIns);
    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    RTRCPTR pRCHelpers = 0;
    int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
    AssertReleaseRC(rc);
    AssertRelease(pRCHelpers);
    LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
             pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
    return pRCHelpers;
}
Beispiel #20
0
/**
 * PFNRTMPWORKER worker for executing Mp events on the target CPU.
 *
 * @param    idCpu          The current CPU Id.
 * @param    pvArg          Opaque pointer to event type (online/offline).
 * @param    pvIgnored1     Ignored.
 */
static void rtMpNotificationSolOnCurrentCpu(RTCPUID idCpu, void *pvArg, void *pvIgnored1)
{
    NOREF(pvIgnored1);
    NOREF(idCpu);

    PRTMPARGS pArgs = (PRTMPARGS)pvArg;
    AssertRelease(pArgs && pArgs->idCpu == RTMpCpuId());
    Assert(pArgs->pvUser1);
    Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));

    RTMPEVENT enmMpEvent = *(RTMPEVENT *)pArgs->pvUser1;
    rtMpNotificationDoCallbacks(enmMpEvent, pArgs->idCpu);
}
Beispiel #21
0
/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetR0Helpers} */
static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
{
    PDMDEV_ASSERT_DEVINS(pDevIns);
    PVM pVM = pDevIns->Internal.s.pVMR3;
    VM_ASSERT_EMT(pVM);
    PCPDMIOAPICHLPR0 pR0Helpers = 0;
    int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);
    AssertReleaseRC(rc);
    AssertRelease(pR0Helpers);
    LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
             pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
    return pR0Helpers;
}
Beispiel #22
0
/**
 * Notification that the framebuffer has completed the
 * asynchronous resize processing
 *
 * @returns COM status code
 */
STDMETHODIMP Display::ResizeCompleted()
{
    LogFlow(("Display::ResizeCompleted\n"));

    // this is only valid for external framebuffers
    if (!mFramebuffer)
        return E_FAIL;

    /* Set the flag indicating that the resize has completed and display data need to be updated. */
    bool f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress);
    AssertRelease(f);NOREF(f);

    return S_OK;
}
Beispiel #23
0
	void writeFile(FileLocalization fileLocalization, const char* filepath, const void* buffer, size_t size)
	{
#if defined(USES_WINDOWS8_DESKTOP) || defined(USES_WINDOWS_OPENGL)
		FILE* file = NULL;
		errno_t res = _wfopen_s(&file, getFullPathUnicode(fileLocalization, filepath).c_str(), L"wb");
		Assert(res == 0);
		fwrite(buffer, size, 1, file);
		fclose(file);
#elif defined(USES_WINDOWS8_METRO)
		BasicReaderWriter^ writer = ref new BasicReaderWriter(getStorageFolder(fileLocalization));

		auto bytes = ref new Platform::Array<unsigned char>((int)size);
		memcpy(bytes->Data, buffer, size);

		//Concurrency::task<void> t = writer->WriteDataAsync(getFilePath(filepath), bytes);
		//t.wait();

		try
		{
			size_t res = static_cast<size_t>(writer->WriteData(getFilePath(filepath), bytes));
			AssertRelease(res == size);
		}
		catch (Platform::FailureException^ exception)
		{
			AssertRelease(false);
		}
#elif defined(USES_LINUX)
		std::wstring fullpath = getFullPathUnicode(fileLocalization, filepath);
		FILE* file = fopen(Utils::convertWStringToString(fullpath).c_str(), "wb");
		Assert(file != NULL);
		fwrite(buffer, size, 1, file);
		fclose(file);
#else
	#error
#endif
	}
RTCString RTCString::substrCP(size_t pos /*= 0*/, size_t n /*= npos*/) const
{
    RTCString ret;

    if (n)
    {
        const char *psz;

        if ((psz = c_str()))
        {
            RTUNICP cp;

            // walk the UTF-8 characters until where the caller wants to start
            size_t i = pos;
            while (*psz && i--)
                if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
                    return ret;     // return empty string on bad encoding

            const char *pFirst = psz;

            if (n == npos)
                // all the rest:
                ret = pFirst;
            else
            {
                i = n;
                while (*psz && i--)
                    if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
                        return ret;     // return empty string on bad encoding

                size_t cbCopy = psz - pFirst;
                if (cbCopy)
                {
                    ret.reserve(cbCopy + 1); // may throw bad_alloc
#ifndef RT_EXCEPTIONS_ENABLED
                    AssertRelease(capacity() >= cbCopy + 1);
#endif
                    memcpy(ret.m_psz, pFirst, cbCopy);
                    ret.m_cch = cbCopy;
                    ret.m_psz[cbCopy] = '\0';
                }
            }
        }
    }

    return ret;
}
RTDECL(int)  RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx)
{
    /*
     * Validate.
     */
    PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);

#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
    AssertRelease(pThis->Owner == RTThreadNativeSelf());
    ASMAtomicUoWriteSize(&pThis->Owner, NIL_RTNATIVETHREAD);
#endif
    up(&pThis->Semaphore);
    IPRT_DEBUG_SEMS_STATE(pThis, 'u');
    return VINF_SUCCESS;
}
Beispiel #26
0
/**
 *  Framebuffer has been resized.
 *  Read the new display data and unlock the framebuffer.
 *
 *  @thread EMT
 */
void Display::handleResizeCompletedEMT (void)
{
    LogFlowFunc(("\n"));
    if (mFramebuffer)
    {
        /* Framebuffer has completed the resize. Update the connector data. */
        updateDisplayData();

        mpDrv->pUpPort->pfnSetRenderVRAM (mpDrv->pUpPort, true);

        /* Unlock framebuffer. */
        mFramebuffer->Unlock();
    }

    /* Go into non resizing state. */
    bool f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_Void, ResizeStatus_UpdateDisplayData);
    AssertRelease(f);NOREF(f);
}
Beispiel #27
0
/** @interface_method_impl{PDMPICHLPR3,pfnGetRCHelpers} */
static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
{
    PDMDEV_ASSERT_DEVINS(pDevIns);
    PVM pVM = pDevIns->Internal.s.pVMR3;
    VM_ASSERT_EMT(pVM);

    RTRCPTR pRCHelpers = NIL_RTRCPTR;
    if (!HMIsEnabled(pVM))
    {
        int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPicHlp", &pRCHelpers);
        AssertReleaseRC(rc);
        AssertRelease(pRCHelpers);
    }

    LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
             pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
    return pRCHelpers;
}
Beispiel #28
0
VirtualBox::ClientWatcher::ClientWatcher(const ComObjPtr<VirtualBox> &pVirtualBox) :
    mVirtualBox(pVirtualBox),
    mThread(NIL_RTTHREAD),
    mUpdateReq(CWUPDATEREQARG),
    mLock(LOCKCLASS_OBJECTSTATE)
{
#if defined(RT_OS_WINDOWS)
    /* Misc state. */
    mfTerminate         = false;
    mcMsWait            = INFINITE;
    mcActiveSubworkers  = 0;

    /* Update request.  The UpdateReq event is also used to wake up subthreads. */
    mfUpdateReq         = false;
    mUpdateReq          = ::CreateEvent(NULL /*pSecAttr*/, TRUE /*fManualReset*/, FALSE /*fInitialState*/, NULL /*pszName*/);
    AssertRelease(mUpdateReq != NULL);

    /* Initialize the handle array. */
    for (uint32_t i = 0; i < RT_ELEMENTS(mahWaitHandles); i++)
        mahWaitHandles[i] = NULL;
    for (uint32_t i = 0; i < RT_ELEMENTS(mahWaitHandles); i += CW_MAX_HANDLES_PER_THREAD)
        mahWaitHandles[i] = mUpdateReq;
    mcWaitHandles = 1;

#elif defined(RT_OS_OS2)
    RTSemEventCreate(&mUpdateReq);
#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
    RTSemEventCreate(&mUpdateReq);
    /* start with high timeouts, nothing to do */
    ASMAtomicUoWriteU8(&mUpdateAdaptCtr, 0);
#else
# error "Port me!"
#endif

    int vrc = RTThreadCreate(&mThread,
                             worker,
                             (void *)this,
                             0,
                             RTTHREADTYPE_MAIN_WORKER,
                             RTTHREADFLAGS_WAITABLE,
                             "Watcher");
    AssertRC(vrc);
}
/**
 * Returns the physical address for a virtual address.
 *
 * @param pv        The virtual address.
 *
 * @returns The physical address corresponding to @a pv.
 */
static uint64_t rtR0MemObjSolVirtToPhys(void *pv)
{
    struct hat *pHat         = NULL;
    pfn_t       PageFrameNum = 0;
    uintptr_t   uVirtAddr    = (uintptr_t)pv;

    if (SOL_IS_KRNL_ADDR(pv))
        pHat = kas.a_hat;
    else
    {
        proc_t *pProcess = (proc_t *)RTR0ProcHandleSelf();
        AssertRelease(pProcess);
        pHat = pProcess->p_as->a_hat;
    }

    PageFrameNum = hat_getpfnum(pHat, (caddr_t)(uVirtAddr & PAGEMASK));
    AssertReleaseMsg(PageFrameNum != PFN_INVALID, ("rtR0MemObjSolVirtToPhys failed. pv=%p\n", pv));
    return (((uint64_t)PageFrameNum << PAGE_SHIFT) | (uVirtAddr & PAGE_OFFSET_MASK));
}
Beispiel #30
0
RTDECL(void*) VBoxVBVAExBIterNext(PVBVAEXBUFFERBACKWARDITER pIter, uint32_t *pcbBuffer, bool *pfProcessed)
{
    PVBVAEXBUFFERCONTEXT pCtx = pIter->Base.pCtx;
    struct VBVABUFFER *pVBVA = pCtx->pVBVA;
    uint32_t indexRecordFirstUncompleted = pCtx->indexRecordFirstUncompleted;
    if (!vboxVBVAExIsEntryInRange(indexRecordFirstUncompleted, pIter->Base.iCurRecord, pVBVA->indexRecordFree))
        return NULL;

    void *pvBuffer = vboxVBVAExIterCur(&pIter->Base, pVBVA, pcbBuffer, pfProcessed);
    AssertRelease(pvBuffer);

    /* even if the command gets completed by the time we're doing the pCtx->pVBVA->aRecords[pIter->Base.iCurRecord].cbRecord below,
     * the pCtx->pVBVA->aRecords[pIter->Base.iCurRecord].cbRecord will still be valid, as it can only be modified by a submitter,
     * and we are in a submitter context now */
    pIter->Base.iCurRecord = vboxVBVAExSubst(pIter->Base.iCurRecord, 1, VBVA_MAX_RECORDS);
    pIter->Base.off32CurCmd = vboxVBVAExSubst(pIter->Base.off32CurCmd, pCtx->pVBVA->aRecords[pIter->Base.iCurRecord].cbRecord, pVBVA->cbData);

    return pvBuffer;
}