SUPDrv-solaris.c revision cfa7d08dfc1259a88f151c4a65b7dddba9ac3d91
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * VBoxDrv - The VirtualBox Support Driver - Solaris specifics.
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * Copyright (C) 2006-2012 Oracle Corporation
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * This file is part of VirtualBox Open Source Edition (OSE), as
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * available from http://www.virtualbox.org. This file is free software;
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * you can redistribute it and/or modify it under the terms of the GNU
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * General Public License (GPL) as published by the Free Software
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * Foundation, in version 2 as it comes in the "COPYING" file of the
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * The contents of this file may alternatively be used under the terms
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * of the Common Development and Distribution License Version 1.0
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * VirtualBox OSE distribution, in which case the provisions of the
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * CDDL are applicable instead of those of the GPL.
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * You may elect to license modified versions of this file under the
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * terms and conditions of either the GPL or the CDDL or both.
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster/*******************************************************************************
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster* Header Files *
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster*******************************************************************************/
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster#undef u /* /usr/include/sys/user.h:249:1 is where this is defined to (curproc->p_user). very cool. */
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster/*******************************************************************************
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster* Defined Constants And Macros *
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster*******************************************************************************/
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster/** The system device name. */
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster/** The user device name. */
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster/** The module description as seen in 'modinfo'. */
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster/** Maximum number of driver instances. */
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster/*******************************************************************************
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster* Internal Functions *
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster*******************************************************************************/
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int mode, cred_t *pCred, int *pVal);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t Cmd);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t Cmd);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisQuiesceNotNeeded(dev_info_t *pDip);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int Cmd, int Mode, intptr_t pArgs);
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster/*******************************************************************************
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster* Global Variables *
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster*******************************************************************************/
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * cb_ops: for drivers that support char/block entry points
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * dev_ops: for driver device operations
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster 0, /* ref count */
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * modldrv: export driver specifics to the kernel
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster DEVICE_DESC " " VBOX_VERSION_STRING "r" RT_XSTR(VBOX_SVN_REV),
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * modlinkage: export install/remove/info to the kernel
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Fosterstatic struct modlinkage g_VBoxDrvSolarisModLinkage =
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster MODREV_1, /* loadable module system revision */
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster NULL /* terminate array of linkage structures */
4d6be67a34a8652a5fb6e2c2d9f57387e2a686c4Allan Foster * State info for each open file handle.
static void *g_pVBoxDrvSolarisState;
int _init(void)
if (pModCtl)
if (!rc)
if (!rc)
return rc;
int _fini(void)
if (rc != 0)
return rc;
switch (enmCmd)
case DDI_ATTACH:
int rc;
#ifdef USE_SESSION_HASH
return DDI_FAILURE;
#ifdef VBOX_WITH_HARDENING
#ifdef USE_SESSION_HASH
return DDI_SUCCESS;
return DDI_FAILURE;
case DDI_RESUME:
return DDI_SUCCESS;
return DDI_FAILURE;
return DDI_FAILURE;
switch (enmCmd)
case DDI_DETACH:
#ifndef USE_SESSION_HASH
return DDI_SUCCESS;
case DDI_SUSPEND:
return DDI_SUCCESS;
return DDI_FAILURE;
return DDI_SUCCESS;
int rc;
#ifndef USE_SESSION_HASH
unsigned iOpenInstance;
if (!pState)
return ENXIO;
unsigned iHash;
int instance;
if (pState)
return ENXIO;
#ifndef USE_SESSION_HASH
if (!pState)
return EFAULT;
if (!pSession)
return EFAULT;
if (pSession)
while (pSession)
if (!pSession)
LogRel(("VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n", (int)Process));
return EFAULT;
static int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cred_t *pCred, int *pVal)
#ifndef USE_SESSION_HASH
if (!pState)
return EINVAL;
if (!pSession)
return DDI_SUCCESS;
if (!pSession)
LogRel(("VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x Dev=%#x\n",
return EINVAL;
#ifndef IOCPARM_LEN
int rc;
} StackBuf;
LogRel(("VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
return EINVAL;
return EFAULT;
LogRel(("VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
return EINVAL;
LogRel(("VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
return EINVAL;
LogRel(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
return ENOMEM;
LogRel(("VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
return EFAULT;
return rc;
return VERR_INVALID_POINTER;
if (pSession)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
switch (rc)
case VINF_SUCCESS: return 0;
return EPERM;
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)
#if defined(VBOX_WITH_NATIVE_SOLARIS_LOADING) \
&& !defined(VBOX_WITHOUT_NATIVE_R0_LOADER)
int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
char *pszSubDir = RTStrAPrintf2("../../../../../../../../../../..%.*s", pszName - pszFilename - 1, pszFilename);
if (!pszSubDir)
return VERR_NO_STR_MEMORY;
extern int swaploaded;
swaploaded = 0;
return VERR_LDR_GENERAL_FAILURE;
if (!pModCtl)
return VERR_LDR_GENERAL_FAILURE;
if (!pModCtl)
return VERR_LDR_GENERAL_FAILURE;
if (rc != 0)
return VINF_SUCCESS;
int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
if (!*ppvValue)
return VINF_SUCCESS;
if (!uValue)
return VERR_SYMBOL_NOT_FOUND;
return VINF_SUCCESS;
int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
return VERR_LDR_MISMATCH_NATIVE;
int rc;
while (iSym-- > 0)
if (!uValue)
LogRel(("supdrvOSLdrLoad on %s failed to resolve the exported symbol: '%s'\n", pImage->szName, pszSymbol));
LogRel(("supdrvOSLdrLoad on %s symbol out of range: %p (%s) \n", pImage->szName, offSymbol, pszSymbol));
case SUPLDRLOADEP_VMMR0:
rc = supdrvSolLdrResolvEp(pImage, "VMMR0EntryFast", (void **)&pReq->u.In.EP.VMMR0.pvVMMR0EntryFast);
case SUPLDRLOADEP_SERVICE:
return VERR_NOT_SUPPORTED;
return rc;
if (rc)
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
return VERR_NOT_SUPPORTED;
return VERR_NOT_SUPPORTED;
return VERR_NOT_SUPPORTED;