SUPDrv-linux.c revision 833e61de8bb4cce493af884821fdd51d01c75048
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * VBoxDrv - The VirtualBox Support Driver - Linux specifics.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * Copyright (C) 2006-2007 Oracle Corporation
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * available from http://www.virtualbox.org. This file is free software;
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * you can redistribute it and/or modify it under the terms of the GNU
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * General Public License (GPL) as published by the Free Software
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * The contents of this file may alternatively be used under the terms
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * of the Common Development and Distribution License Version 1.0
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * VirtualBox OSE distribution, in which case the provisions of the
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * CDDL are applicable instead of those of the GPL.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * You may elect to license modified versions of this file under the
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * terms and conditions of either the GPL or the CDDL or both.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/*******************************************************************************
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync* Header Files *
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync*******************************************************************************/
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/** @todo figure out the exact version number */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/*******************************************************************************
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync* Defined Constants And Macros *
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync*******************************************************************************/
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/* check kernel version */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/* devfs defines */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync#if defined(CONFIG_DEVFS_FS) && !defined(CONFIG_VBOXDRV_AS_MISC)
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync#endif /* CONFIG_DEV_FS && !CONFIG_VBOXDEV_AS_MISC */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync# error "CONFIG_X86_HIGH_ENTRY is not supported by VBoxDrv at this time."
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/*******************************************************************************
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync* Internal Functions *
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync*******************************************************************************/
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int VBoxDrvLinuxInit(void);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic void VBoxDrvLinuxUnload(void);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int VBoxDrvLinuxCreate(struct inode *pInode, struct file *pFilp);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int VBoxDrvLinuxClose(struct inode *pInode, struct file *pFilp);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic long VBoxDrvLinuxIOCtl(struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int VBoxDrvProbe(struct platform_device *pDev);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int VBoxDrvSuspend(struct platform_device *pDev, pm_message_t State);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int VBoxDrvResume(struct platform_device *pDev);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/*******************************************************************************
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync* Global Variables *
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync*******************************************************************************/
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * Device extention & session data association structure.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/** Module major number */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/** Saved major device number */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync#endif /* !CONFIG_VBOXDRV_AS_MISC */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/** Module parameter.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * Not prefixed because the name is used by macros and the end of this file. */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncstatic int force_async_tsc = 0;
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/** The module name. */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * Memory for the executable memory heap (in IPRT).
19a258565a4d24e5a0af62f626943ac9b898d957vboxsyncextern uint8_t g_abExecMemory[1572864]; /* 1.5 MB */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync__asm__(".section execmemory, \"awx\", @progbits\n\t"
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync ".align 32\n\t"
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync ".globl g_abExecMemory\n"
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync "g_abExecMemory:\n\t"
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync ".zero 1572864\n\t"
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync ".type g_abExecMemory, @object\n\t"
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync ".size g_abExecMemory, 1572864\n\t"
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync ".text\n\t");
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/** The file_operations structure. */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync/** The miscdevice structure. */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync .suspend = VBoxDrvSuspend, /* before entering deep sleep */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync .resume = VBoxDrvResume, /* after wakeup from deep sleep */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync .freeze = VBoxDrvSuspend, /* before creating hibernation image */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync .restore = VBoxDrvResume, /* after waking up from hibernation */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync /** @todo .shutdown? */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync#endif /* VBOX_WITH_SUSPEND_NOTIFICATION */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * Initialize module.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * @returns appropriate status code.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * Check for synchronous/asynchronous TSC mode.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync printk(KERN_DEBUG DEVICE_NAME ": Found %u processor cores.\n", (unsigned)RTMpGetOnlineCount());
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync printk(KERN_ERR DEVICE_NAME ": Can't register misc device! rc=%d\n", rc);
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync#else /* !CONFIG_VBOXDRV_AS_MISC */
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync * Register character device.
19a258565a4d24e5a0af62f626943ac9b898d957vboxsync rc = register_chrdev((dev_t)g_iModuleMajor, DEVICE_NAME, &gFileOpsVBoxDrv);
if (rc < 0)
return rc;
if (DEVICE_MAJOR != 0)
rc = 0;
# ifdef CONFIG_DEVFS_FS
if (!rc)
#ifdef RT_ARCH_AMD64
if (rc == 0)
if (rc == 0)
#ifdef VBOX_HRTIMER
return rc;
#ifdef CONFIG_VBOXDRV_AS_MISC
return rc;
int rc;
#ifdef CONFIG_VBOXDRV_AS_MISC
if (rc < 0)
# ifdef CONFIG_DEVFS_FS
int rc;
Log(("VBoxDrvLinuxCreate: pFilp=%p pid=%d/%d %s\n", pFilp, RTProcSelf(), current->pid, current->comm));
#ifdef VBOX_WITH_HARDENING
return -EPERM;
if (!rc)
* @param State message type, see Documentation/power/devices.txt.
#ifdef HAVE_UNLOCKED_IOCTL
static int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
#ifdef HAVE_UNLOCKED_IOCTL
int rc;
lock_kernel();
return rc;
int rc;
Log6(("VBoxDrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p pid=%d/%d\n", pFilp, uCmd, (void *)ulArg, RTProcSelf(), current->pid));
return -EFAULT;
Log(("VBoxDrvLinuxIOCtl: bad header magic %#x; uCmd=%#x\n", Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, uCmd));
return -EINVAL;
return -E2BIG;
Log(("VBoxDrvLinuxIOCtl: bad ioctl cbBuf=%#x _IOC_SIZE=%#x; uCmd=%#x.\n", cbBuf, _IOC_SIZE(uCmd), uCmd));
return -EINVAL;
OSDBGPRINT(("VBoxDrvLinuxIOCtl: failed to allocate buffer of %d bytes for uCmd=%#x.\n", cbBuf, uCmd));
return -ENOMEM;
return -EFAULT;
Log(("VBoxDrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p failed, rc=%d\n", pFilp, uCmd, (void *)ulArg, rc));
return rc;
return VERR_INVALID_POINTER;
if (pSession)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
return force_async_tsc != 0;
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)
return VERR_NOT_SUPPORTED;
switch (rc)
case VINF_SUCCESS: return 0;
return -EPERM;
#ifdef MODULE_VERSION