Ejemplo n.º 1
0
/**
 * Register VBoxGuest char device
 */
static int vgdrvDarwinCharDevInit(void)
{
    int rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestDarwin");
    if (RT_SUCCESS(rc))
    {
        /*
         * Registering ourselves as a character device.
         */
        g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
        if (g_iMajorDeviceNo >= 0)
        {
            g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
            if (g_hDevFsDeviceSys != NULL)
            {
                /*
                 * Register a sleep/wakeup notification callback.
                 */
                g_pSleepNotifier = registerPrioritySleepWakeInterest(&vgdrvDarwinSleepHandler, &g_DevExt, NULL);
                if (g_pSleepNotifier != NULL)
                {
                    return KMOD_RETURN_SUCCESS;
                }
            }
        }
        vgdrvDarwinCharDevRemove();
    }
    return KMOD_RETURN_FAILURE;
}
Ejemplo n.º 2
0
/**
 * Initializes the thread database.
 *
 * @returns iprt status code.
 */
DECLHIDDEN(int) rtThreadInit(void)
{
#ifdef IN_RING3
    int rc = VINF_ALREADY_INITIALIZED;
    if (g_ThreadRWSem == NIL_RTSEMRW)
    {
        /*
         * We assume the caller is the 1st thread, which we'll call 'main'.
         * But first, we'll create the semaphore.
         */
        rc = RTSemRWCreateEx(&g_ThreadRWSem, RTSEMRW_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
        if (RT_SUCCESS(rc))
        {
            rc = rtThreadNativeInit();
            if (RT_SUCCESS(rc))
                rc = rtThreadAdopt(RTTHREADTYPE_DEFAULT, 0, RTTHREADINT_FLAGS_MAIN, "main");
            if (RT_SUCCESS(rc))
                rc = rtSchedNativeCalcDefaultPriority(RTTHREADTYPE_DEFAULT);
            if (RT_SUCCESS(rc))
            {
                g_frtThreadInitialized = true;
                return VINF_SUCCESS;
            }

            /* failed, clear out */
            RTSemRWDestroy(g_ThreadRWSem);
            g_ThreadRWSem = NIL_RTSEMRW;
        }
    }

#elif defined(IN_RING0)
    int rc;
    /*
     * Create the spinlock and to native init.
     */
    Assert(g_ThreadSpinlock == NIL_RTSPINLOCK);
    rc = RTSpinlockCreate(&g_ThreadSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTThread");
    if (RT_SUCCESS(rc))
    {
        rc = rtThreadNativeInit();
        if (RT_SUCCESS(rc))
        {
            g_frtThreadInitialized = true;
            return VINF_SUCCESS;
        }

        /* failed, clear out */
        RTSpinlockDestroy(g_ThreadSpinlock);
        g_ThreadSpinlock = NIL_RTSPINLOCK;
    }
#else
# error "!IN_RING0 && !IN_RING3"
#endif
    return rc;
}
/**
 * Does ring-0 per-VM GIM Hyper-V initialization.
 *
 * @returns VBox status code.
 * @param   pVM     Pointer to the VM.
 */
VMMR0_INT_DECL(int) gimR0HvInitVM(PVM pVM)
{
    AssertPtr(pVM);
    Assert(GIMIsEnabled(pVM));

    PGIMHV pHv = &pVM->gim.s.u.Hv;
    Assert(pHv->hSpinlockR0 == NIL_RTSPINLOCK);

    int rc = RTSpinlockCreate(&pHv->hSpinlockR0, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "Hyper-V");
    return rc;
}
Ejemplo n.º 4
0
RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
{
    *ppTimer = NULL;

    /*
     * We don't support the fancy MP features.
     */
    if (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
        return VERR_NOT_SUPPORTED;

    /*
     * Lazy initialize the spinlock.
     */
    if (g_Spinlock == NIL_RTSPINLOCK)
    {
        RTSPINLOCK Spinlock;
        int rc = RTSpinlockCreate(&Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTTimerOS2");
        AssertRCReturn(rc, rc);
        //bool fRc;
        //ASMAtomicCmpXchgSize(&g_Spinlock, Spinlock, NIL_RTSPINLOCK, fRc);
        //if (!fRc)
        if (!ASMAtomicCmpXchgPtr((void * volatile *)&g_Spinlock, Spinlock, NIL_RTSPINLOCK))
            RTSpinlockDestroy(Spinlock);
    }

    /*
     * Allocate and initialize the timer handle.
     */
    PRTTIMER pTimer = (PRTTIMER)RTMemAlloc(sizeof(*pTimer));
    if (!pTimer)
        return VERR_NO_MEMORY;

    pTimer->u32Magic = RTTIMER_MAGIC;
    pTimer->pNext = NULL;
    pTimer->fSuspended = true;
    pTimer->pfnTimer = pfnTimer;
    pTimer->pvUser = pvUser;
    pTimer->u64NanoInterval = u64NanoInterval;
    pTimer->u64StartTS = 0;

    /*
     * Insert the timer into the list (LIFO atm).
     */
    RTSpinlockAcquire(g_Spinlock);
    g_u32ChangeNo++;
    pTimer->pNext = g_pTimerHead;
    g_pTimerHead = pTimer;
    g_cTimers++;
    RTSpinlockRelease(g_Spinlock);

    *ppTimer = pTimer;
    return VINF_SUCCESS;
}
Ejemplo n.º 5
0
/**
 * 32-bit Ring-0 initialization.
 *
 * @returns 0 on success, non-zero on failure.
 * @param   pszArgs     Pointer to the device arguments.
 */
DECLASM(int) VBoxDrvInit(const char *pszArgs)
{
    /*
     * Initialize the runtime.
     */
    int rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        Log(("VBoxDrvInit: pszArgs=%s\n", pszArgs));

        /*
         * Initialize the device extension.
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Initialize the session hash table.
             */
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvOS2");
            if (RT_SUCCESS(rc))
            {
                /*
                 * Process the commandline. Later.
                 */
                bool fVerbose = true;

                /*
                 * Success
                 */
                if (fVerbose)
                {
                    strcpy(&g_szInitText[0],
                           "\r\n"
                           "VirtualBox.org Support Driver for OS/2 version " VBOX_VERSION_STRING "\r\n"
                           "Copyright (C) 2007 Knut St. Osmundsen\r\n"
                           "Copyright (C) 2007 Oracle Corporation\r\n");
                    g_cchInitText = strlen(&g_szInitText[0]);
                }
                return VINF_SUCCESS;
            }
            g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: RTSpinlockCreate failed, rc=%Rrc\n", rc);
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
            g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: supdrvInitDevExt failed, rc=%Rrc\n", rc);
        RTR0Term();
    }
    else
        g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: RTR0Init failed, rc=%Rrc\n", rc);
    return rc;
}
Ejemplo n.º 6
0
DECLHIDDEN(int) rtR0PowerNotificationInit(void)
{
    int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTPowerNotifySpinLock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTR0Power");
    if (RT_SUCCESS(rc))
    {
        /** @todo OS specific init here */
        return rc;
#if 0
        RTSpinlockDestroy(g_hRTPowerNotifySpinLock);
        g_hRTPowerNotifySpinLock = NIL_RTSPINLOCK;
#endif
    }
    return rc;
}
Ejemplo n.º 7
0
DECLHIDDEN(int) rtR0MpNotificationInit(void)
{
    int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTMpNotifySpinLock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "RTR0Mp");
    if (RT_SUCCESS(rc))
    {
        rc = rtR0MpNotificationNativeInit();
        if (RT_SUCCESS(rc))
            return rc;

        RTSpinlockDestroy(g_hRTMpNotifySpinLock);
        g_hRTMpNotifySpinLock = NIL_RTSPINLOCK;
    }
    return rc;
}
Ejemplo n.º 8
0
/**
 * Donate read+write+execute memory to the exec heap.
 *
 * This API is specific to AMD64 and Linux/GNU. A kernel module that desires to
 * use RTMemExecAlloc on AMD64 Linux/GNU will have to donate some statically
 * allocated memory in the module if it wishes for GCC generated code to work.
 * GCC can only generate modules that work in the address range ~2GB to ~0
 * currently.
 *
 * The API only accept one single donation.
 *
 * @returns IPRT status code.
 * @param   pvMemory    Pointer to the memory block.
 * @param   cb          The size of the memory block.
 */
RTR0DECL(int) RTR0MemExecDonate(void *pvMemory, size_t cb)
{
    int rc;
    AssertReturn(g_HeapExec == NIL_RTHEAPSIMPLE, VERR_WRONG_ORDER);

    rc = RTSpinlockCreate(&g_HeapExecSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTR0MemExecDonate");
    if (RT_SUCCESS(rc))
    {
        rc = RTHeapSimpleInit(&g_HeapExec, pvMemory, cb);
        if (RT_FAILURE(rc))
            rtR0MemExecCleanup();
    }
    return rc;
}
Ejemplo n.º 9
0
/**
 * Initializes the VBoxUSB filter manager.
 *
 * @returns IPRT status code.
 */
int VBoxUSBFilterInit(void)
{
#ifdef VBOXUSBFILTERMGR_USB_SPINLOCK
    int rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxUSBFilter");
#else
    int rc = RTSemFastMutexCreate(&g_Mtx);
#endif
    if (RT_SUCCESS(rc))
    {
        /* not really required, but anyway... */
        for (unsigned i = USBFILTERTYPE_FIRST; i < RT_ELEMENTS(g_aLists); i++)
            g_aLists[i].pHead = g_aLists[i].pTail = NULL;
    }
    return rc;
}
Ejemplo n.º 10
0
static int vboxNetAdpSlotCreate(PVBOXNETADPGLOBALS pGlobals, unsigned uUnit, PVBOXNETADP pNew)
{
    int rc;

    pNew->MyPort.u32Version             = INTNETTRUNKIFPORT_VERSION;
    pNew->MyPort.pfnRetain              = vboxNetAdpPortRetain;
    pNew->MyPort.pfnRelease             = vboxNetAdpPortRelease;
    pNew->MyPort.pfnDisconnectAndRelease= vboxNetAdpPortDisconnectAndRelease;
    pNew->MyPort.pfnSetState            = vboxNetAdpPortSetState;
    pNew->MyPort.pfnWaitForIdle         = vboxNetAdpPortWaitForIdle;
    pNew->MyPort.pfnXmit                = vboxNetAdpPortXmit;
    pNew->MyPort.u32VersionEnd          = INTNETTRUNKIFPORT_VERSION;
    pNew->pSwitchPort                   = NULL;
    pNew->pGlobals                      = pGlobals;
    pNew->hSpinlock                     = NIL_RTSPINLOCK;
    pNew->enmState                      = kVBoxNetAdpState_Invalid;
    pNew->cRefs                         = 0;
    pNew->cBusy                         = 0;
    pNew->hEventIdle                    = NIL_RTSEMEVENT;

    rc = RTSpinlockCreate(&pNew->hSpinlock);
    if (RT_SUCCESS(rc))
    {
        rc = RTSemEventCreate(&pNew->hEventIdle);
        if (RT_SUCCESS(rc))
        {
            rc = vboxNetAdpOsInit(pNew);
            if (RT_SUCCESS(rc))
            {
                return rc;
            }
            RTSemEventDestroy(pNew->hEventIdle);
            pNew->hEventIdle = NIL_RTSEMEVENT;
        }
        RTSpinlockDestroy(pNew->hSpinlock);
        pNew->hSpinlock = NIL_RTSPINLOCK;
    }
    return rc;
}
RTDECL(int) RTMemPoolCreate(PRTMEMPOOL phMemPool, const char *pszName)
{
    AssertPtr(phMemPool);
    AssertPtr(pszName);
    Assert(*pszName);

    size_t          cchName  = strlen(pszName);
    PRTMEMPOOLINT   pMemPool = (PRTMEMPOOLINT)RTMemAlloc(RT_UOFFSETOF_DYN(RTMEMPOOLINT, szName[cchName + 1]));
    if (!pMemPool)
        return VERR_NO_MEMORY;
    int rc = RTSpinlockCreate(&pMemPool->hSpinLock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "RTMemPoolCreate");
    if (RT_SUCCESS(rc))
    {
        pMemPool->u32Magic = RTMEMPOOL_MAGIC;
        pMemPool->pHead = NULL;
        pMemPool->cEntries = 0;
        pMemPool->pvUser = NULL;
        memcpy(pMemPool->szName, pszName, cchName);
        *phMemPool = pMemPool;
        return VINF_SUCCESS;
    }
    RTMemFree(pMemPool);
    return rc;
}
Ejemplo n.º 12
0
/**
 * Kernel entry points
 */
int _init(void)
{
    LogFlowFunc((DEVICE_NAME ":_init\n"));

    /*
     * Prevent module autounloading.
     */
    modctl_t *pModCtl = mod_getctl(&g_VBoxDrvSolarisModLinkage);
    if (pModCtl)
        pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
    else
        LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));

    /*
     * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
     */
    int rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Initialize the device extension
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Initialize the session hash table.
             */
            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab));
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvSol");
            if (RT_SUCCESS(rc))
            {
                rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8);
                if (!rc)
                {
                    rc = mod_install(&g_VBoxDrvSolarisModLinkage);
                    if (!rc)
                        return rc; /* success */

                    ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
                    LogRel((DEVICE_NAME ":mod_install failed! rc=%d\n", rc));
                }
                else
                    LogRel((DEVICE_NAME ":failed to initialize soft state.\n"));

                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
            {
                LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
                rc = RTErrConvertToErrno(rc);
            }
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
        {
            LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
            rc = RTErrConvertToErrno(rc);
        }
        RTR0TermForced();
    }
    else
    {
        LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: failed to init R0Drv\n"));
        rc = RTErrConvertToErrno(rc);
    }
    memset(&g_DevExt, 0, sizeof(g_DevExt));

    return rc;
}
/**
 * Kernel entry points
 */
int _init(void)
{
#if 0    /* No IPRT logging before RTR0Init() is done! */
    LogFlowFunc(("vboxdrv:_init\n"));
#endif

    /*
     * Prevent module autounloading.
     */
    modctl_t *pModCtl = mod_getctl(&g_VBoxDrvSolarisModLinkage);
    if (pModCtl)
        pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
    else
        cmn_err(CE_NOTE, "vboxdrv: failed to disable autounloading!\n");

    /*
     * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
     */
    int rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Initialize the device extension
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            cmn_err(CE_CONT, "!tsc::mode %s @ tentative %lu Hz\n", SUPGetGIPModeName(g_DevExt.pGip), g_DevExt.pGip->u64CpuHz);

            /*
             * Initialize the session hash table.
             */
            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab));
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvSol");
            if (RT_SUCCESS(rc))
            {
                rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8);
                if (!rc)
                {
                    rc = mod_install(&g_VBoxDrvSolarisModLinkage);
                    if (!rc)
                        return rc; /* success */

                    ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
                    LogRel(("vboxdrv: mod_install failed! rc=%d\n", rc));
                }
                else
                    LogRel(("vboxdrv: failed to initialize soft state.\n"));

                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
            {
                LogRel(("VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
                rc = RTErrConvertToErrno(rc);
            }
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
        {
            LogRel(("VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
            rc = EINVAL;
        }
        RTR0TermForced();
    }
    else
    {
        LogRel(("VBoxDrvSolarisAttach: failed to init R0Drv\n"));
        rc = RTErrConvertToErrno(rc);
    }
    memset(&g_DevExt, 0, sizeof(g_DevExt));

    return rc;
}
Ejemplo n.º 14
0
static status_t VBoxGuestHaikuAttach(const pci_info *pDevice)
{
    status_t status;
    int rc = VINF_SUCCESS;
    int iResId = 0;
    struct VBoxGuestDeviceState *pState = &sState;
    static const char *const     s_apszGroups[] = VBOX_LOGGROUP_NAMES;
    PRTLOGGER                    pRelLogger;

    AssertReturn(pDevice, B_BAD_VALUE);

    cUsers = 0;

    /*
     * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
     */
    rc = RTR0Init(0);
    if (RT_FAILURE(rc))
    {
        /** @todo r=ramshankar: use dprintf here. */
        LogFunc(("RTR0Init failed.\n"));
        return ENXIO;
    }

    rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestHaiku");
    if (RT_FAILURE(rc))
    {
        LogRel(("VBoxGuestHaikuAttach: RTSpinlock create failed. rc=%Rrc\n", rc));
        return ENXIO;
    }

#ifdef DO_LOG
    /*
     * Create the release log.
     * (We do that here instead of common code because we want to log
     * early failures using the LogRel macro.)
     */
    rc = RTLogCreate(&pRelLogger, 0 | RTLOGFLAGS_PREFIX_THREAD /* fFlags */, "all",
                     "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
                     RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER | RTLOGDEST_USER, NULL);
    dprintf(MODULE_NAME ": RTLogCreate: %d\n", rc);
    if (RT_SUCCESS(rc))
    {
        //RTLogGroupSettings(pRelLogger, g_szLogGrp);
        //RTLogFlags(pRelLogger, g_szLogFlags);
        //RTLogDestinations(pRelLogger, "/var/log/vboxguest.log");
        RTLogRelSetDefaultInstance(pRelLogger);
        RTLogSetDefaultInstance(pRelLogger); //XXX
    }
#endif

    /*
     * Allocate I/O port resource.
     */
    pState->uIOPortBase = pDevice->u.h0.base_registers[0];
    /* @todo check flags for IO? */
    if (pState->uIOPortBase)
    {
        /*
         * Map the MMIO region.
         */
        uint32 phys = pDevice->u.h0.base_registers[1];
        /* @todo Check flags for mem? */
        pState->VMMDevMemSize    = pDevice->u.h0.base_register_sizes[1];
        pState->iVMMDevMemAreaId = map_physical_memory("VirtualBox Guest MMIO", phys, pState->VMMDevMemSize,
                                                       B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
                                                       &pState->pMMIOBase);
        if (pState->iVMMDevMemAreaId > 0 && pState->pMMIOBase)
        {
            /*
             * Call the common device extension initializer.
             */
            rc = VBoxGuestInitDevExt(&g_DevExt, pState->uIOPortBase, pState->pMMIOBase, pState->VMMDevMemSize,
#if ARCH_BITS == 64
                                     VBOXOSTYPE_Haiku_x64,
#else
                                     VBOXOSTYPE_Haiku,
#endif
                                     VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
            if (RT_SUCCESS(rc))
            {
                /*
                 * Add IRQ of VMMDev.
                 */
                pState->iIrqResId = pDevice->u.h0.interrupt_line;
                rc = VBoxGuestHaikuAddIRQ(pState);
                if (RT_SUCCESS(rc))
                {
                    LogRel((MODULE_NAME ": loaded successfully\n"));
                    return B_OK;
                }

                LogRel((MODULE_NAME ":VBoxGuestInitDevExt failed.\n"));
                VBoxGuestDeleteDevExt(&g_DevExt);
            }
            else
                LogRel((MODULE_NAME ":VBoxGuestHaikuAddIRQ failed.\n"));
        }
        else
            LogRel((MODULE_NAME ":MMIO region setup failed.\n"));
    }
    else
        LogRel((MODULE_NAME ":IOport setup failed.\n"));

    RTR0Term();
    return ENXIO;
}
Ejemplo n.º 15
0
/**
 * Creates a new instance.
 *
 * @returns VBox status code.
 * @param   pGlobals            The globals.
 * @param   pszName             The instance name.
 * @param   ppDevPort           Where to store the pointer to our port interface.
 */
static int vboxPciNewInstance(PVBOXRAWPCIGLOBALS pGlobals,
                              uint32_t           u32HostAddress,
                              uint32_t           fFlags,
                              PRAWPCIPERVM       pVmCtx,
                              PRAWPCIDEVPORT     *ppDevPort,
                              uint32_t           *pfDevFlags)
{
    int             rc;
    PVBOXRAWPCIINS  pNew = (PVBOXRAWPCIINS)RTMemAllocZ(sizeof(*pNew));
    if (!pNew)
        return VERR_NO_MEMORY;

    pNew->pGlobals                      = pGlobals;
    pNew->hSpinlock                     = NIL_RTSPINLOCK;
    pNew->cRefs                         = 1;
    pNew->pNext                         = NULL;
    pNew->HostPciAddress                = u32HostAddress;
    pNew->pVmCtx                        = pVmCtx;

    pNew->DevPort.u32Version            = RAWPCIDEVPORT_VERSION;

    pNew->DevPort.pfnInit               = vboxPciDevInit;
    pNew->DevPort.pfnDeinit             = vboxPciDevDeinit;
    pNew->DevPort.pfnDestroy            = vboxPciDevDestroy;
    pNew->DevPort.pfnGetRegionInfo      = vboxPciDevGetRegionInfo;
    pNew->DevPort.pfnMapRegion          = vboxPciDevMapRegion;
    pNew->DevPort.pfnUnmapRegion        = vboxPciDevUnmapRegion;
    pNew->DevPort.pfnPciCfgRead         = vboxPciDevPciCfgRead;
    pNew->DevPort.pfnPciCfgWrite        = vboxPciDevPciCfgWrite;
    pNew->DevPort.pfnPciCfgRead         = vboxPciDevPciCfgRead;
    pNew->DevPort.pfnPciCfgWrite        = vboxPciDevPciCfgWrite;
    pNew->DevPort.pfnRegisterIrqHandler = vboxPciDevRegisterIrqHandler;
    pNew->DevPort.pfnUnregisterIrqHandler = vboxPciDevUnregisterIrqHandler;
    pNew->DevPort.pfnPowerStateChange   = vboxPciDevPowerStateChange;
    pNew->DevPort.u32VersionEnd         = RAWPCIDEVPORT_VERSION;

    rc = RTSpinlockCreate(&pNew->hSpinlock);

    if (RT_SUCCESS(rc))
    {
        rc = RTSemFastMutexCreate(&pNew->hFastMtx);
        if (RT_SUCCESS(rc))
        {
            rc = pNew->DevPort.pfnInit(&pNew->DevPort, fFlags);
            if (RT_SUCCESS(rc))
            {
                *ppDevPort = &pNew->DevPort;

                pNew->pNext = pGlobals->pInstanceHead;
                pGlobals->pInstanceHead = pNew;
            }
            else
            {
                RTSemFastMutexDestroy(pNew->hFastMtx);
                RTSpinlockDestroy(pNew->hSpinlock);
                RTMemFree(pNew);
            }
        }
    }

    return rc;
}
Ejemplo n.º 16
0
/**
 * Start the kernel module.
 */
static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;
#ifdef DEBUG
    printf("VBoxDrvDarwinStart\n");
#endif

    /*
     * Initialize IPRT.
     */
    rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Initialize the device extension.
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Initialize the session hash table.
             */
            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); /* paranoia */
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvDarwin");
            if (RT_SUCCESS(rc))
            {
                /*
                 * Registering ourselves as a character device.
                 */
                g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
                if (g_iMajorDeviceNo >= 0)
                {
#ifdef VBOX_WITH_HARDENING
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
#else
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
#endif
                    if (g_hDevFsDeviceSys)
                    {
                        g_hDevFsDeviceUsr = devfs_make_node(makedev(g_iMajorDeviceNo, 1), DEVFS_CHAR,
                                                            UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_USR);
                        if (g_hDevFsDeviceUsr)
                        {
                            LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
                                    VBOX_SVN_REV, SUPDRV_IOC_VERSION, SUPDRV_IDC_VERSION, g_iMajorDeviceNo));

                            /* Register a sleep/wakeup notification callback */
                            g_pSleepNotifier = registerPrioritySleepWakeInterest(&VBoxDrvDarwinSleepHandler, &g_DevExt, NULL);
                            if (g_pSleepNotifier == NULL)
                                LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));

                            /* Find kernel symbols that are kind of optional. */
                            vboxdrvDarwinResolveSymbols();
                            return KMOD_RETURN_SUCCESS;
                        }

                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,1),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_USR));
                        devfs_remove(g_hDevFsDeviceSys);
                        g_hDevFsDeviceSys = NULL;
                    }
                    else
                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_SYS));

                    cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
                    g_iMajorDeviceNo = -1;
                }
                else
                    LogRel(("VBoxDrv: cdevsw_add failed (%d)\n", g_iMajorDeviceNo));
                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
                LogRel(("VBoxDrv: RTSpinlockCreate failed (rc=%d)\n", rc));
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
            printf("VBoxDrv: failed to initialize device extension (rc=%d)\n", rc);
        RTR0TermForced();
    }
    else
        printf("VBoxDrv: failed to initialize IPRT (rc=%d)\n", rc);

    memset(&g_DevExt, 0, sizeof(g_DevExt));
    return KMOD_RETURN_FAILURE;
}
Ejemplo n.º 17
0
RTDECL(int) RTHandleTableCreateEx(PRTHANDLETABLE phHandleTable, uint32_t fFlags, uint32_t uBase, uint32_t cMax,
                                  PFNRTHANDLETABLERETAIN pfnRetain, void *pvUser)
{
    PRTHANDLETABLEINT   pThis;
    uint32_t            cLevel1;
    size_t              cb;

    /*
     * Validate input.
     */
    AssertPtrReturn(phHandleTable, VERR_INVALID_POINTER);
    *phHandleTable = NIL_RTHANDLETABLE;
    AssertPtrNullReturn(pfnRetain, VERR_INVALID_POINTER);
    AssertReturn(!(fFlags & ~RTHANDLETABLE_FLAGS_MASK), VERR_INVALID_PARAMETER);
    AssertReturn(cMax > 0, VERR_INVALID_PARAMETER);
    AssertReturn(UINT32_MAX - cMax >= uBase, VERR_INVALID_PARAMETER);

    /*
     * Adjust the cMax value so it is a multiple of the 2nd level tables.
     */
    if (cMax >= UINT32_MAX - RTHT_LEVEL2_ENTRIES)
        cMax = UINT32_MAX - RTHT_LEVEL2_ENTRIES + 1;
    cMax = ((cMax + RTHT_LEVEL2_ENTRIES - 1) / RTHT_LEVEL2_ENTRIES) * RTHT_LEVEL2_ENTRIES;

    cLevel1 = cMax / RTHT_LEVEL2_ENTRIES;
    Assert(cLevel1 * RTHT_LEVEL2_ENTRIES == cMax);

    /*
     * Allocate the structure, include the 1st level lookup table
     * if it's below the threshold size.
     */
    cb = sizeof(RTHANDLETABLEINT);
    if (cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD)
        cb = RT_ALIGN(cb, sizeof(void *)) + cLevel1 * sizeof(void *);
    pThis = (PRTHANDLETABLEINT)RTMemAllocZ(cb);
    if (!pThis)
        return VERR_NO_MEMORY;

    /*
     * Initialize it.
     */
    pThis->u32Magic = RTHANDLETABLE_MAGIC;
    pThis->fFlags = fFlags;
    pThis->uBase = uBase;
    pThis->cCur = 0;
    pThis->hSpinlock = NIL_RTSPINLOCK;
    if (cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD)
        pThis->papvLevel1 = (void **)((uint8_t *)pThis + RT_ALIGN(sizeof(*pThis), sizeof(void *)));
    else
        pThis->papvLevel1 = NULL;
    pThis->pfnRetain = pfnRetain;
    pThis->pvRetainUser = pvUser;
    pThis->cMax = cMax;
    pThis->cCurAllocated = 0;
    pThis->cLevel1 = cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD ? cLevel1 : 0;
    pThis->iFreeHead = NIL_RTHT_INDEX;
    pThis->iFreeTail = NIL_RTHT_INDEX;
    if (fFlags & RTHANDLETABLE_FLAGS_LOCKED)
    {
        int rc = RTSpinlockCreate(&pThis->hSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "RTHandleTableCreateEx");
        if (RT_FAILURE(rc))
        {
            RTMemFree(pThis);
            return rc;
        }
    }

    *phHandleTable = pThis;
    return VINF_SUCCESS;
}