SUPDrv-darwin.cpp revision c03ad2650049d583f98f1ecd61a7a9725792afc5
* available from http://www.virtualbox.org. This file is free software;
#include "../SUPDrvInternal.h"
#ifdef VBOX_WITH_HOST_VMX
static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
static int VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess);
static IOReturn VBoxDrvDarwinSleepHandler(void *pvTarget, void *pvRefCon, UInt32 uMessageType, IOService *pProvider, void *pvMessageArgument, vm_size_t argSize);
static void vboxdrvDarwinResolveSymbols(void);
virtual void free(void);
#ifdef SUPDRV_WITH_MSR_PROBER
int rc;
#ifdef DEBUG
if (g_iMajorDeviceNo >= 0)
#ifdef VBOX_WITH_HARDENING
if (g_hDevFsDeviceSys)
if (g_hDevFsDeviceUsr)
LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
return KMOD_RETURN_SUCCESS;
LogRel(("VBoxDrv: devfs_make_node(makedev(%d,1),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_USR));
LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_SYS));
return KMOD_RETURN_FAILURE;
static void vboxdrvDarwinResolveSymbols(void)
LogRel(("VBoxDrv: failed to resolve vmx stuff: vmx_resume=%Rrc vmx_suspend=%Rrc vmx_use_count=%Rrc", rc1, rc2, rc3));
#ifdef SUPDRV_WITH_MSR_PROBER
int rc = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "rdmsr_carefully", (void **)&g_pfnRdMsrCarefully);
rc = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "rdmsr64_carefully", (void **)&g_pfnRdMsr64Carefully);
# ifdef RT_ARCH_AMD64 /* Missing 64 in name, so if implemented on 32-bit it could have different signature. */
rc = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "wrmsr_carefully", (void **)&g_pfnWrMsr64Carefully);
int rc;
if (g_pSleepNotifier)
#ifdef DEBUG
return KMOD_RETURN_SUCCESS;
#ifdef DEBUG_DARWIN_GIP
return EACCES;
return EIO;
if (pCred)
if (pSession)
#ifdef DEBUG_DARWIN_GIP
OSDBGPRINT(("VBoxDrvDarwinOpen: pid=%d '%s' pSession=%p rc=%d\n", proc_pid(pProcess), szName, pSession, rc));
Log(("VBoxDrvDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess)));
static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
while (pSession && (pSession->Process != Process || pSession->fUnrestricted != fUnrestricted || !pSession->fOpened))
OSDBGPRINT(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#lx\n",
return EINVAL;
int rc;
&& fUnrestricted)
return rc;
static int VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess)
LogFlow(("VBoxDrvDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess));
OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: cbReq=%#x < %#x; iCmd=%#lx\n", cbReq, (int)sizeof(*pHdr), iCmd));
return EINVAL;
return EINVAL;
OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x) != %#x; iCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cbReq, iCmd));
return EINVAL;
OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd));
return rc;
return EINVAL;
return EINVAL;
if (!pHdr)
OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd));
return ENOMEM;
if (pvPageBuf)
return rc;
return EINVAL;
if (pUser)
OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, iCmd));
if (pvPageBuf)
if (pUser)
if (pvPageBuf)
Log(("VBoxDrvDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc));
return rc;
return VERR_INVALID_POINTER;
if (pSession)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
IOReturn VBoxDrvDarwinSleepHandler(void * /* pvTarget */, void *pvRefCon, UInt32 uMessageType, IOService * /* pProvider */, void * /* pvMessageArgument */, vm_size_t /* argSize */)
#ifdef VBOX_WITH_HOST_VMX
int rc;
&& g_pVmxUseCount)
if (fEnable)
host_vmxoff();
return rc;
return VERR_NOT_SUPPORTED;
#ifdef VBOX_WITH_HOST_VMX
* Note! The host_vmxon/off code is still race prone since, but this is
if ( g_pVmxUseCount
&& *g_pVmxUseCount > 0)
#ifdef VBOX_WITH_HOST_VMX
if ( fSuspended
&& g_pfnVmxResume)
if (pEntry)
int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
return VERR_NOT_SUPPORTED;
int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
return VERR_NOT_SUPPORTED;
int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
return VERR_NOT_SUPPORTED;
#ifdef SUPDRV_WITH_MSR_PROBER
typedef struct SUPDRVDARWINMSRARGS
int rc;
static DECLCALLBACK(void) supdrvDarwinMsrProberReadOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
else if (g_pfnRdMsrCarefully)
return VERR_NOT_SUPPORTED;
return rc;
return VERR_ACCESS_DENIED;
return VINF_SUCCESS;
static DECLCALLBACK(void) supdrvDarwinMsrProberWriteOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
if (!g_pfnWrMsr64Carefully)
return VERR_NOT_SUPPORTED;
return rc;
return VERR_ACCESS_DENIED;
return VINF_SUCCESS;
static DECLCALLBACK(void) supdrvDarwinMsrProberModifyOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
if (!fFaster)
if (rcBefore >= 0)
if (!fFaster)
ASMReloadCR3();
ASMNopPause();
return VERR_NOT_SUPPORTED;
return VINF_SUCCESS;
static void supdrvDarwinResumeBluetoothKbd(void)
if (pDictionary)
if (pIter)
static void supdrvDarwinResumeBuiltinKbd(void)
if (pDictionary)
if (pIter)
switch (rc)
case VINF_SUCCESS: return 0;
return EPERM;
bool fRc;
fRc = false;
return fRc;
bool org_virtualbox_SupDrvClient::initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type)
AssertMsg((RTR0PROCESS)OwningTask == RTR0ProcHandleSelf(), ("%p %p\n", OwningTask, RTR0ProcHandleSelf()));
if (!OwningTask)
LogRel(("org_virtualbox_SupDrvClient::initWithTask: Expected cookie %#x (%s)\n", u32Type, pszProcName));
if (m_pProvider)
if (!pCur)
Log(("org_virtualbox_SupDrvClient::start: created session %p for pid %d\n", m_pSession, (int)RTProcSelf()));
LogFlow(("org_virtualbox_SupDrvClient::start: already got a session for this process (%p)\n", pCur));
if (pSession)
while (pSession)
if (!pSession)
if (pThis)
LogFlow(("org_virtualbox_SupDrvClient::clientClose([%p]) (cur pid=%d proc=%p)\n", this, RTProcSelf(), RTR0ProcHandleSelf()));
if (m_pSession)
terminate();
return kIOReturnSuccess;