/** * 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; }
/** * 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; }
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; }
/** * 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; }
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; }
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; }
/** * 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; }
/** * 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; }
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; }
/** * 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; }
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; }
/** * 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; }
/** * 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; }
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; }