SUPDrv-linux.c revision f1f1251c2af8ab21c414989ae02b81d3a7c3fab8
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * VBoxDrv - The VirtualBox Support Driver - Linux specifics.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Copyright (C) 2006-2007 Sun Microsystems, Inc.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * This file is part of VirtualBox Open Source Edition (OSE), as
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * available from http://www.virtualbox.org. This file is free software;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * you can redistribute it and/or modify it under the terms of the GNU
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * General Public License (GPL) as published by the Free Software
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Foundation, in version 2 as it comes in the "COPYING" file of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
* Clara, CA 95054 USA or visit http://www.sun.com if you need
#include "../SUPDrvInternal.h"
#include "the-linux-kernel.h"
#include "version-generated.h"
# define VBOX_WITH_SUSPEND_NOTIFICATION
#ifdef CONFIG_DEVFS_FS
#ifdef CONFIG_VBOXDRV_AS_MISC
#ifdef CONFIG_X86_LOCAL_APIC
# ifdef VBOX_WITH_HARDENING
# define VBOX_REGISTER_DEVFS() \
DEVICE_NAME) == 0) \
rc; \
# define VBOX_REGISTER_DEVFS() \
DEVICE_MAJOR, 0, \
#ifndef CONFIG_VBOXDRV_AS_MISC
#ifdef CONFIG_X86_HIGH_ENTRY
#ifdef CONFIG_X86_LOCAL_APIC
# if defined(RT_ARCH_AMD64)
extern int nmi_active;
# define nmi_atomic_read(P) *(P)
# define nmi_atomic_set(P, V) *(P) = (V)
# ifndef X86_FEATURE_ARCH_PERFMON
# ifndef MSR_ARCH_PERFMON_EVENTSEL0
#define str(s) #s
#ifndef CONFIG_VBOXDRV_AS_MISC
static int g_iModuleMajor;
static int force_async_tsc = 0;
#ifdef RT_ARCH_AMD64
static int VBoxDrvLinuxInit(void);
static void VBoxDrvLinuxUnload(void);
#ifdef HAVE_UNLOCKED_IOCTL
static int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
static int VBoxDrvLinuxErr2LinuxErr(int);
#ifdef HAVE_UNLOCKED_IOCTL
#ifdef CONFIG_VBOXDRV_AS_MISC
.driver =
.dev =
#ifdef CONFIG_X86_LOCAL_APIC
# ifdef DO_DISABLE_NMI
static int vboxdrvStopK7Watchdog(void)
static int vboxdrvStopP4Watchdog(void)
static int vboxdrvStopIntelArchWatchdog(void)
unsigned ebx;
int stopped = 0;
case X86_VENDOR_AMD:
case X86_VENDOR_INTEL:
if (stopped)
static void DisableLapicNmiWatchdog(void)
static void vboxdrvNmiShutdown(void)
int rc;
#ifdef CONFIG_X86_LOCAL_APIC
# ifdef DO_DISABLE_NMI
switch (nmi_watchdog)
case NMI_LOCAL_APIC:
case NMI_NONE:
return -EINVAL;
goto nmi_activated;
return -EINVAL;
return -EINVAL;
* Check for synchronous/asynchronous TSC mode.
#ifdef CONFIG_VBOXDRV_AS_MISC
if (rc)
return rc;
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;
RTR0Term();
#ifdef CONFIG_VBOXDRV_AS_MISC
return rc;
int rc;
#ifdef CONFIG_VBOXDRV_AS_MISC
if (rc < 0)
# ifdef CONFIG_DEVFS_FS
RTR0Term();
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;
switch (rc)
return -EPERM;
#ifdef MODULE_VERSION