summaryrefslogtreecommitdiff
path: root/src/VBox/HostDrivers/Support
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostDrivers/Support')
-rw-r--r--src/VBox/HostDrivers/Support/Makefile.kmk25
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp18
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrv.c464
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvIDC.h8
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvIOC.h22
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvInternal.h56
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvSem.c4
-rw-r--r--src/VBox/HostDrivers/Support/SUPDrvTracer.cpp21
-rw-r--r--src/VBox/HostDrivers/Support/SUPLib.cpp185
-rw-r--r--src/VBox/HostDrivers/Support/SUPLibInternal.h7
-rw-r--r--src/VBox/HostDrivers/Support/SUPLibSem.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPLibTracerA.asm78
-rw-r--r--src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp4
-rw-r--r--src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp12
-rw-r--r--src/VBox/HostDrivers/Support/SUPSvc.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPSvcGrant.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/SUPSvcInternal.h2
-rw-r--r--src/VBox/HostDrivers/Support/darwin/Info.plist2
-rw-r--r--src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp304
-rw-r--r--src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp21
-rw-r--r--src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c2
-rw-r--r--src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c74
-rw-r--r--src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp17
-rw-r--r--src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c2
-rwxr-xr-xsrc/VBox/HostDrivers/Support/freebsd/files_vboxdrv5
-rw-r--r--src/VBox/HostDrivers/Support/linux/Makefile5
-rw-r--r--src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c219
-rw-r--r--src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c2
-rw-r--r--src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp21
-rw-r--r--src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c2
-rwxr-xr-xsrc/VBox/HostDrivers/Support/linux/files_vboxdrv6
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp23
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def2
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp5
-rw-r--r--src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c2
-rw-r--r--src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c146
-rw-r--r--src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp28
-rw-r--r--src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c2
-rwxr-xr-xsrc/VBox/HostDrivers/Support/solaris/load.sh13
-rw-r--r--src/VBox/HostDrivers/Support/solaris/vboxdrv.conf8
-rw-r--r--src/VBox/HostDrivers/Support/testcase/Makefile.kmk6
-rw-r--r--src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp11
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstInit.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstInt.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstLow.cpp4
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstNtQueryStuff.cpp452
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstPage.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstPin.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp6
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp154
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp297
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm2
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPLib-win.cpp17
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c2
-rw-r--r--src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp2
-rw-r--r--src/VBox/HostDrivers/Support/win/VBoxDrv.inf2
65 files changed, 2091 insertions, 713 deletions
diff --git a/src/VBox/HostDrivers/Support/Makefile.kmk b/src/VBox/HostDrivers/Support/Makefile.kmk
index bd79dd70..5addff09 100644
--- a/src/VBox/HostDrivers/Support/Makefile.kmk
+++ b/src/VBox/HostDrivers/Support/Makefile.kmk
@@ -31,6 +31,9 @@ include $(KBUILD_PATH)/subheader.kmk
# Targets
#
LIBRARIES += SUPR3 SUPR3Static SUPR3HardenedStatic
+ifdef VBOX_WITH_32_ON_64_MAIN_API
+ LIBRARIES += SUPR3-x86
+endif
ifndef VBOX_ONLY_DOCS
if1of ($(VBOX_LDR_FMT), pe lx)
LIBRARIES += SUPR0
@@ -70,19 +73,13 @@ endif # !VBOX_ONLY_DOCS && !VBOX_ONLY_EXTPACKS && !VBOX_ONLY_TESTSUITE
#
# The Ring-3 Support Library (this is linked into the IPRT dll, VBoxRT).
#
-ifneq ($(filter l4%,$(KBUILD_TARGET) $(BUILD_TARGET_SUB)),)
- # L4 has trouble with -pedantic. It also make trouble when inlining is not enabled.
- SUPR3_TEMPLATE = VBOXR3NP
-else
- SUPR3_TEMPLATE = VBOXR3
-endif
+SUPR3_TEMPLATE = VBOXR3NP
SUPR3_DEFS = \
IN_SUP_R3 IN_RT_R3 \
$(if $(VBOX_WITH_SUPSVC),VBOX_WITH_SUPSVC) \
$(if $(VBOX_WITH_MAIN),VBOX_WITH_MAIN,) \
$(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,)
SUPR3_INCS := $(PATH_SUB_CURRENT)
-SUPR3_INCS.l4 = $(L4_INCDIR)
SUPR3_SOURCES = \
SUPLib.cpp \
SUPLibSem.cpp \
@@ -91,6 +88,10 @@ SUPR3_SOURCES = \
SUPR3HardenedVerify.cpp \
$(KBUILD_TARGET)/SUPLib-$(KBUILD_TARGET).cpp
+SUPR3-x86_TEMPLATE = VBoxR3Dll-x86
+SUPR3-x86_EXTENDS = SUPR3
+
+
#
# Static version of SUPR3.
#
@@ -266,7 +267,7 @@ if1of ($(KBUILD_TARGET), darwin linux solaris win)
VBoxDrv_DEFS += VBOX_WITH_DTRACE VBOX_WITH_DTRACE_R0DRV
endif
#VBoxDrv_DEFS.debug += DEBUG_DARWIN_GIP
- #VBoxDrv_DEFS.darwin := VBOX_WITH_HOST_VMX - break raw-mode, hack+enable after 4.2.0!
+ VBoxDrv_DEFS.darwin := VBOX_WITH_HOST_VMX
VBoxDrv_DEFS.linux := \
KBUILD_MODNAME=KBUILD_STR\(vboxdrv\) KBUILD_BASENAME=KBUILD_STR\(vboxdrv\) MODULE CONFIG_VBOXDRV_AS_MISC
ifdef VBOX_LINUX_VERSION_2_4
@@ -281,9 +282,6 @@ if1of ($(KBUILD_TARGET), darwin linux solaris win)
ifdef VBOX_WITHOUT_NATIVE_R0_LOADER
VBoxDrv_DEFS.win += VBOX_WITHOUT_NATIVE_R0_LOADER
endif
- ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
- VBoxDrv_DEFS.win += VBOX_WITH_VMMR0_DISABLE_PREEMPTION
- endif
VBoxDrv_INCS = . $(VBoxDrv_0_OUTDIR)
VBoxDrv_INCS.darwin = ./darwin
@@ -304,7 +302,10 @@ if1of ($(KBUILD_TARGET), darwin linux solaris win)
VBoxDrv_LDFLAGS.win.x86 = -Entry:DriverEntry@8
VBoxDrv_LDFLAGS.win.amd64= -Entry:DriverEntry
- VBoxDrv_SOURCES.darwin = darwin/SUPDrv-darwin.cpp
+ VBoxDrv_SOURCES.darwin = \
+ darwin/SUPDrv-darwin.cpp
+ VBoxDrv_SOURCES.linux = \
+ linux/SUPDrv-linux.c
VBoxDrv_SOURCES.solaris = \
solaris/SUPDrv-solaris.c
VBoxDrv_SOURCES.win = \
diff --git a/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp b/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp
index 828a9b71..03839688 100644
--- a/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp
+++ b/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp
@@ -46,19 +46,19 @@
#ifdef RT_OS_DARWIN
# include VBOX_PATH_MACOSX_DTRACE_H
#elif defined(RT_OS_LINUX)
-/* DTrace experiments with the Unbreakable Enterprise Kernel (UEK)
+/* DTrace experiments with the Unbreakable Enterprise Kernel (UEK)
(Oracle Linux).
- 1. The dtrace.h here is from the dtrace module source, not
+ 1. The dtrace.h here is from the dtrace module source, not
/usr/include/sys/dtrace.h nor /usr/include/dtrace.h.
- 2. To generate the missing entries for the dtrace module in Module.symvers
+ 2. To generate the missing entries for the dtrace module in Module.symvers
of UEK:
nm /lib/modules/....../kernel/drivers/dtrace/dtrace.ko \
| grep _crc_ \
| sed -e 's/^......../0x/' -e 's/ A __crc_/\t/' \
-e 's/$/\tdrivers\/dtrace\/dtrace\tEXPORT_SYMBOL/' \
>> Module.symvers
- 3. No tracepoints in vboxdrv, vboxnet* or vboxpci yet. This requires yasm
- and VBoxTpG and build time. */
+ 3. No tracepoints in vboxdrv, vboxnet* or vboxpci yet. This requires yasm
+ and VBoxTpG and build time. */
# undef UINT8_MAX
# undef UINT16_MAX
# undef UINT32_MAX
@@ -73,14 +73,14 @@
#endif
-/**
- * The UEK DTrace port is trying to be smart and seems to have turned all
+/**
+ * The UEK DTrace port is trying to be smart and seems to have turned all
* errno return codes negative. While this conforms to the linux kernel way of
- * doing things, it breaks with the way the interfaces work on Solaris and
+ * doing things, it breaks with the way the interfaces work on Solaris and
* Mac OS X.
*/
#ifndef FIX_UEK_RC
-# define FIX_UEK_RC(a_rc) (a_rc)
+# define FIX_UEK_RC(a_rc) (a_rc)
#endif
diff --git a/src/VBox/HostDrivers/Support/SUPDrv.c b/src/VBox/HostDrivers/Support/SUPDrv.c
index 2f07360e..580e318d 100644
--- a/src/VBox/HostDrivers/Support/SUPDrv.c
+++ b/src/VBox/HostDrivers/Support/SUPDrv.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -59,8 +59,8 @@
#include <VBox/param.h>
#include <VBox/log.h>
#include <VBox/err.h>
-#include <VBox/vmm/hwacc_svm.h>
-#include <VBox/vmm/hwacc_vmx.h>
+#include <VBox/vmm/hm_svm.h>
+#include <VBox/vmm/hm_vmx.h>
#if defined(RT_OS_SOLARIS) || defined(RT_OS_DARWIN)
# include "dtrace/SUPDrv.h"
@@ -137,6 +137,7 @@ static void supdrvGipUpdate(PSUPDRVDEVEXT pDevExt, uint64_t u64N
static void supdrvGipUpdatePerCpu(PSUPDRVDEVEXT pDevExt, uint64_t u64NanoTS, uint64_t u64TSC,
RTCPUID idCpu, uint8_t idApic, uint64_t iTick);
static void supdrvGipInitCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t u64NanoTS);
+static int supdrvIOCtl_ResumeSuspendedKbds(void);
/*******************************************************************************
@@ -172,6 +173,8 @@ static SUPFUNC g_aFunctions[] =
{ "SUPR0ContAlloc", (void *)SUPR0ContAlloc },
{ "SUPR0ContFree", (void *)SUPR0ContFree },
{ "SUPR0EnableVTx", (void *)SUPR0EnableVTx },
+ { "SUPR0SuspendVTxOnCpu", (void *)SUPR0SuspendVTxOnCpu },
+ { "SUPR0ResumeVTxOnCpu", (void *)SUPR0ResumeVTxOnCpu },
{ "SUPR0GetPagingMode", (void *)SUPR0GetPagingMode },
{ "SUPR0LockMem", (void *)SUPR0LockMem },
{ "SUPR0LowAlloc", (void *)SUPR0LowAlloc },
@@ -233,6 +236,7 @@ static SUPFUNC g_aFunctions[] =
{ "RTHandleTableFreeWithCtx", (void *)RTHandleTableFreeWithCtx },
{ "RTHandleTableLookupWithCtx", (void *)RTHandleTableLookupWithCtx },
{ "RTLogDefaultInstance", (void *)RTLogDefaultInstance },
+ { "RTLogGetDefaultInstance", (void *)RTLogGetDefaultInstance },
{ "RTLogLoggerExV", (void *)RTLogLoggerExV },
{ "RTLogPrintfV", (void *)RTLogPrintfV },
{ "RTLogRelDefaultInstance", (void *)RTLogRelDefaultInstance },
@@ -363,6 +367,12 @@ static SUPFUNC g_aFunctions[] =
{ "RTStrPrintfExV", (void *)RTStrPrintfExV },
{ "RTStrPrintfV", (void *)RTStrPrintfV },
{ "RTThreadCreate", (void *)RTThreadCreate },
+ { "RTThreadCtxHooksAreRegistered", (void *)RTThreadCtxHooksAreRegistered },
+ { "RTThreadCtxHooksCreate", (void *)RTThreadCtxHooksCreate },
+ { "RTThreadCtxHooksDeregister", (void *)RTThreadCtxHooksDeregister },
+ { "RTThreadCtxHooksRegister", (void *)RTThreadCtxHooksRegister },
+ { "RTThreadCtxHooksRelease", (void *)RTThreadCtxHooksRelease },
+ { "RTThreadCtxHooksRetain", (void *)RTThreadCtxHooksRetain },
{ "RTThreadGetName", (void *)RTThreadGetName },
{ "RTThreadGetNative", (void *)RTThreadGetNative },
{ "RTThreadGetType", (void *)RTThreadGetType },
@@ -453,7 +463,7 @@ int VBOXCALL supdrvInitDevExt(PSUPDRVDEVEXT pDevExt, size_t cbSession)
* Initialize it.
*/
memset(pDevExt, 0, sizeof(*pDevExt));
- rc = RTSpinlockCreate(&pDevExt->Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "SUPDrvDevExt");
+ rc = RTSpinlockCreate(&pDevExt->Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "SUPDrvDevExt");
if (RT_SUCCESS(rc))
{
rc = RTSpinlockCreate(&pDevExt->hGipSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "SUPDrvGip");
@@ -654,17 +664,25 @@ void VBOXCALL supdrvDeleteDevExt(PSUPDRVDEVEXT pDevExt)
* Create session.
*
* @returns IPRT status code.
- * @param pDevExt Device extension.
- * @param fUser Flag indicating whether this is a user or kernel session.
- * @param ppSession Where to store the pointer to the session data.
+ * @param pDevExt Device extension.
+ * @param fUser Flag indicating whether this is a user or kernel
+ * session.
+ * @param fUnrestricted Unrestricted access (system) or restricted access
+ * (user)?
+ * @param ppSession Where to store the pointer to the session data.
*/
-int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, PSUPDRVSESSION *ppSession)
+int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted, PSUPDRVSESSION *ppSession)
{
+ int rc;
+ PSUPDRVSESSION pSession;
+
+ if (!SUP_IS_DEVEXT_VALID(pDevExt))
+ return VERR_INVALID_PARAMETER;
+
/*
* Allocate memory for the session data.
*/
- int rc;
- PSUPDRVSESSION pSession = *ppSession = (PSUPDRVSESSION)RTMemAllocZ(pDevExt->cbSession);
+ pSession = *ppSession = (PSUPDRVSESSION)RTMemAllocZ(pDevExt->cbSession);
if (pSession)
{
/* Initialize session data. */
@@ -672,13 +690,15 @@ int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, PSUPDRVSESSI
if (!rc)
{
rc = RTHandleTableCreateEx(&pSession->hHandleTable,
- RTHANDLETABLE_FLAGS_LOCKED | RTHANDLETABLE_FLAGS_CONTEXT,
+ RTHANDLETABLE_FLAGS_LOCKED_IRQ_SAFE | RTHANDLETABLE_FLAGS_CONTEXT,
1 /*uBase*/, 32768 /*cMax*/, supdrvSessionObjHandleRetain, pSession);
if (RT_SUCCESS(rc))
{
Assert(pSession->Spinlock != NIL_RTSPINLOCK);
pSession->pDevExt = pDevExt;
pSession->u32Cookie = BIRD_INV;
+ pSession->fUnrestricted = fUnrestricted;
+ pSession->cRefs = 1;
/*pSession->pLdrUsage = NULL;
pSession->pVM = NULL;
pSession->pUsage = NULL;
@@ -724,33 +744,6 @@ int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, PSUPDRVSESSI
/**
- * Shared code for cleaning up a session.
- *
- * @param pDevExt Device extension.
- * @param pSession Session data.
- * This data will be freed by this routine.
- */
-void VBOXCALL supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
-{
- VBOXDRV_SESSION_CLOSE(pSession);
-
- /*
- * Cleanup the session first.
- */
- supdrvCleanupSession(pDevExt, pSession);
-
- /*
- * Free the rest of the session stuff.
- */
- RTSpinlockDestroy(pSession->Spinlock);
- pSession->Spinlock = NIL_RTSPINLOCK;
- pSession->pDevExt = NULL;
- RTMemFree(pSession);
- LogFlow(("supdrvCloseSession: returns\n"));
-}
-
-
-/**
* Shared code for cleaning up a session (but not quite freeing it).
*
* This is primarily intended for MAC OS X where we have to clean up the memory
@@ -760,7 +753,7 @@ void VBOXCALL supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
* @param pSession Session data.
* This data will be freed by this routine.
*/
-void VBOXCALL supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
+static void supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
{
int rc;
PSUPDRVBUNDLE pBundle;
@@ -969,6 +962,71 @@ void VBOXCALL supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSessio
/**
+ * Shared code for cleaning up a session.
+ *
+ * @param pDevExt Device extension.
+ * @param pSession Session data.
+ * This data will be freed by this routine.
+ */
+static void supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
+{
+ VBOXDRV_SESSION_CLOSE(pSession);
+
+ /*
+ * Cleanup the session first.
+ */
+ supdrvCleanupSession(pDevExt, pSession);
+
+ /*
+ * Free the rest of the session stuff.
+ */
+ RTSpinlockDestroy(pSession->Spinlock);
+ pSession->Spinlock = NIL_RTSPINLOCK;
+ pSession->pDevExt = NULL;
+ RTMemFree(pSession);
+ LogFlow(("supdrvCloseSession: returns\n"));
+}
+
+
+/**
+ * Retain a session to make sure it doesn't go away while it is in use.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param pSession Session data.
+ */
+uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession)
+{
+ uint32_t cRefs;
+ AssertPtrReturn(pSession, UINT32_MAX);
+ AssertReturn(SUP_IS_SESSION_VALID(pSession), UINT32_MAX);
+
+ cRefs = ASMAtomicIncU32(&pSession->cRefs);
+ AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pSession));
+ return cRefs;
+}
+
+
+/**
+ * Releases a given session.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param pSession Session data.
+ */
+uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession)
+{
+ uint32_t cRefs;
+ AssertPtrReturn(pSession, UINT32_MAX);
+ AssertReturn(SUP_IS_SESSION_VALID(pSession), UINT32_MAX);
+
+ cRefs = ASMAtomicDecU32(&pSession->cRefs);
+ AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pSession));
+ if (cRefs == 0)
+ supdrvCloseSession(pSession->pDevExt, pSession);
+ return cRefs;
+}
+
+
+/**
* RTHandleTableDestroy callback used by supdrvCleanupSession.
*
* @returns IPRT status code, see SUPR0ObjAddRef.
@@ -1026,8 +1084,8 @@ int VBOXCALL supdrvIOCtlFast(uintptr_t uIOCtl, VMCPUID idCpu, PSUPDRVDEVEXT pDev
case SUP_IOCTL_FAST_DO_RAW_RUN:
pDevExt->pfnVMMR0EntryFast(pSession->pVM, idCpu, SUP_VMMR0_DO_RAW_RUN);
break;
- case SUP_IOCTL_FAST_DO_HWACC_RUN:
- pDevExt->pfnVMMR0EntryFast(pSession->pVM, idCpu, SUP_VMMR0_DO_HWACC_RUN);
+ case SUP_IOCTL_FAST_DO_HM_RUN:
+ pDevExt->pfnVMMR0EntryFast(pSession->pVM, idCpu, SUP_VMMR0_DO_HM_RUN);
break;
case SUP_IOCTL_FAST_DO_NOP:
pDevExt->pfnVMMR0EntryFast(pSession->pVM, idCpu, SUP_VMMR0_DO_NOP);
@@ -1078,7 +1136,7 @@ static int supdrvCheckInvalidChar(const char *pszStr, const char *pszChars)
* @param pSession Session data.
* @param pReqHdr The request header.
*/
-static int supdrvIOCtlInner(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
+static int supdrvIOCtlInnerUnrestricted(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
{
/*
* Validation macros
@@ -1755,7 +1813,6 @@ static int supdrvIOCtlInner(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESS
/* validate */
PSUPVTCAPS pReq = (PSUPVTCAPS)pReqHdr;
REQ_CHECK_SIZES(SUP_IOCTL_VT_CAPS);
- REQ_CHECK_EXPR(SUP_IOCTL_VT_CAPS, pReq->Hdr.cbIn <= SUP_IOCTL_VT_CAPS_SIZE_IN);
/* execute */
pReq->Hdr.rc = SUPR0QueryVTCaps(pSession, &pReq->u.Out.Caps);
@@ -1834,6 +1891,100 @@ static int supdrvIOCtlInner(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESS
return 0;
}
+ case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_RESUME_SUSPENDED_KBDS):
+ {
+ /* validate */
+ REQ_CHECK_SIZES(SUP_IOCTL_RESUME_SUSPENDED_KBDS);
+
+ pReqHdr->rc = supdrvIOCtl_ResumeSuspendedKbds();
+ return 0;
+ }
+
+ default:
+ Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
+ break;
+ }
+ return VERR_GENERAL_FAILURE;
+}
+
+
+/**
+ * I/O Control inner worker for the restricted operations.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_PARAMETER if the request is invalid.
+ *
+ * @param uIOCtl Function number.
+ * @param pDevExt Device extention.
+ * @param pSession Session data.
+ * @param pReqHdr The request header.
+ */
+static int supdrvIOCtlInnerRestricted(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
+{
+ /*
+ * The switch.
+ */
+ switch (SUP_CTL_CODE_NO_SIZE(uIOCtl))
+ {
+ case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_COOKIE):
+ {
+ PSUPCOOKIE pReq = (PSUPCOOKIE)pReqHdr;
+ REQ_CHECK_SIZES(SUP_IOCTL_COOKIE);
+ if (strncmp(pReq->u.In.szMagic, SUPCOOKIE_MAGIC, sizeof(pReq->u.In.szMagic)))
+ {
+ OSDBGPRINT(("SUP_IOCTL_COOKIE: invalid magic %.16s\n", pReq->u.In.szMagic));
+ pReq->Hdr.rc = VERR_INVALID_MAGIC;
+ return 0;
+ }
+
+ /*
+ * Match the version.
+ * The current logic is very simple, match the major interface version.
+ */
+ if ( pReq->u.In.u32MinVersion > SUPDRV_IOC_VERSION
+ || (pReq->u.In.u32MinVersion & 0xffff0000) != (SUPDRV_IOC_VERSION & 0xffff0000))
+ {
+ OSDBGPRINT(("SUP_IOCTL_COOKIE: Version mismatch. Requested: %#x Min: %#x Current: %#x\n",
+ pReq->u.In.u32ReqVersion, pReq->u.In.u32MinVersion, SUPDRV_IOC_VERSION));
+ pReq->u.Out.u32Cookie = 0xffffffff;
+ pReq->u.Out.u32SessionCookie = 0xffffffff;
+ pReq->u.Out.u32SessionVersion = 0xffffffff;
+ pReq->u.Out.u32DriverVersion = SUPDRV_IOC_VERSION;
+ pReq->u.Out.pSession = NULL;
+ pReq->u.Out.cFunctions = 0;
+ pReq->Hdr.rc = VERR_VERSION_MISMATCH;
+ return 0;
+ }
+
+ /*
+ * Fill in return data and be gone.
+ * N.B. The first one to change SUPDRV_IOC_VERSION shall makes sure that
+ * u32SessionVersion <= u32ReqVersion!
+ */
+ /** @todo Somehow validate the client and negotiate a secure cookie... */
+ pReq->u.Out.u32Cookie = pDevExt->u32Cookie;
+ pReq->u.Out.u32SessionCookie = pSession->u32Cookie;
+ pReq->u.Out.u32SessionVersion = SUPDRV_IOC_VERSION;
+ pReq->u.Out.u32DriverVersion = SUPDRV_IOC_VERSION;
+ pReq->u.Out.pSession = pSession;
+ pReq->u.Out.cFunctions = 0;
+ pReq->Hdr.rc = VINF_SUCCESS;
+ return 0;
+ }
+
+ case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_VT_CAPS):
+ {
+ /* validate */
+ PSUPVTCAPS pReq = (PSUPVTCAPS)pReqHdr;
+ REQ_CHECK_SIZES(SUP_IOCTL_VT_CAPS);
+
+ /* execute */
+ pReq->Hdr.rc = SUPR0QueryVTCaps(pSession, &pReq->u.Out.Caps);
+ if (RT_FAILURE(pReq->Hdr.rc))
+ pReq->Hdr.cbOut = sizeof(pReq->Hdr);
+ return 0;
+ }
+
default:
Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
break;
@@ -1895,9 +2046,12 @@ int VBOXCALL supdrvIOCtl(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION
}
/*
- * Hand it to an inner function to avoid lots of unnecessary return tracepoints
+ * Hand it to an inner function to avoid lots of unnecessary return tracepoints.
*/
- rc = supdrvIOCtlInner(uIOCtl, pDevExt, pSession, pReqHdr);
+ if (pSession->fUnrestricted)
+ rc = supdrvIOCtlInnerUnrestricted(uIOCtl, pDevExt, pSession, pReqHdr);
+ else
+ rc = supdrvIOCtlInnerRestricted(uIOCtl, pDevExt, pSession, pReqHdr);
VBOXDRV_IOCTL_RETURN(pSession, uIOCtl, pReqHdr, pReqHdr->rc, rc);
return rc;
@@ -1999,7 +2153,7 @@ int VBOXCALL supdrvIDC(uintptr_t uReq, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSe
pReq->u.Out.uDriverVersion = SUPDRV_IDC_VERSION;
pReq->u.Out.uDriverRevision = VBOX_SVN_REV;
- pReq->Hdr.rc = supdrvCreateSession(pDevExt, false /* fUser */, &pSession);
+ pReq->Hdr.rc = supdrvCreateSession(pDevExt, false /* fUser */, true /*fUnrestricted*/, &pSession);
if (RT_FAILURE(pReq->Hdr.rc))
{
OSDBGPRINT(("SUPDRV_IDC_REQ_CONNECT: failed to create session, rc=%d\n", pReq->Hdr.rc));
@@ -2016,7 +2170,7 @@ int VBOXCALL supdrvIDC(uintptr_t uReq, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSe
{
REQ_CHECK_IDC_SIZE(SUPDRV_IDC_REQ_DISCONNECT, sizeof(*pReqHdr));
- supdrvCloseSession(pDevExt, pSession);
+ supdrvSessionRelease(pSession);
return pReqHdr->rc = VINF_SUCCESS;
}
@@ -3187,9 +3341,61 @@ SUPR0DECL(int) SUPR0EnableVTx(bool fEnable)
}
-/** @todo document me */
+/**
+ * Suspends hardware virtualization extensions using the native OS API.
+ *
+ * This is called prior to entering raw-mode context.
+ *
+ * @returns @c true if suspended, @c false if not.
+ */
+SUPR0DECL(bool) SUPR0SuspendVTxOnCpu(void)
+{
+#ifdef RT_OS_DARWIN
+ return supdrvOSSuspendVTxOnCpu();
+#else
+ return false;
+#endif
+}
+
+
+/**
+ * Resumes hardware virtualization extensions using the native OS API.
+ *
+ * This is called after to entering raw-mode context.
+ *
+ * @param fSuspended The return value of SUPR0SuspendVTxOnCpu.
+ */
+SUPR0DECL(void) SUPR0ResumeVTxOnCpu(bool fSuspended)
+{
+#ifdef RT_OS_DARWIN
+ supdrvOSResumeVTxOnCpu(fSuspended);
+#else
+ Assert(!fSuspended);
+#endif
+}
+
+
+/**
+ * Queries the AMD-V and VT-x capabilities of the calling CPU.
+ *
+ * @returns VBox status code.
+ * @retval VERR_VMX_NO_VMX
+ * @retval VERR_VMX_MSR_SMX_VMXON_DISABLED
+ * @retval VERR_VMX_MSR_VMXON_DISABLED
+ * @retval VERR_VMX_MSR_LOCKING_FAILED
+ * @retval VERR_SVM_NO_SVM
+ * @retval VERR_SVM_DISABLED
+ * @retval VERR_UNSUPPORTED_CPU if not identifiable as an AMD, Intel or VIA
+ * (centaur) CPU.
+ *
+ * @param pSession The session handle.
+ * @param pfCaps Where to store the capabilities.
+ */
SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps)
{
+ int rc = VERR_UNSUPPORTED_CPU;
+ RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+
/*
* Input validation.
*/
@@ -3197,39 +3403,72 @@ SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps)
AssertPtrReturn(pfCaps, VERR_INVALID_POINTER);
*pfCaps = 0;
-
+ /* We may modify MSRs and re-read them, disable preemption so we make sure we don't migrate CPUs. */
+ RTThreadPreemptDisable(&PreemptState);
if (ASMHasCpuId())
{
- uint32_t u32FeaturesECX;
- uint32_t u32Dummy;
- uint32_t u32FeaturesEDX;
- uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX, u32AMDFeatureEDX, u32AMDFeatureECX;
- uint64_t val;
-
- ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
- ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
- /* Query AMD features. */
- ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, &u32AMDFeatureECX, &u32AMDFeatureEDX);
-
- if ( u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX
- && u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX
- && u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX
+ uint32_t fFeaturesECX, fFeaturesEDX, uDummy;
+ uint32_t uMaxId, uVendorEBX, uVendorECX, uVendorEDX;
+ uint64_t u64FeatMsr;
+
+ ASMCpuId(0, &uMaxId, &uVendorEBX, &uVendorECX, &uVendorEDX);
+ ASMCpuId(1, &uDummy, &uDummy, &fFeaturesECX, &fFeaturesEDX);
+
+ if ( ASMIsValidStdRange(uMaxId)
+ && ( ASMIsIntelCpuEx( uVendorEBX, uVendorECX, uVendorEDX)
+ || ASMIsViaCentaurCpuEx(uVendorEBX, uVendorECX, uVendorEDX) )
)
{
- if ( (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
- && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
- && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
+ if ( (fFeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
+ && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
+ && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
)
{
- val = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
- /*
- * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
- * Once the lock bit is set, this MSR can no longer be modified.
- */
- if ( (val & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
- == (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK) /* enabled and locked */
- || !(val & MSR_IA32_FEATURE_CONTROL_LOCK) /* not enabled, but not locked either */
- )
+ /** @todo Unify code with hmR0InitIntelCpu(). */
+ uint64_t u64FeatMsr = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+ bool const fInSmxMode = RT_BOOL(ASMGetCR4() & X86_CR4_SMXE);
+ bool fMsrLocked = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_LOCK);
+ bool fSmxVmxAllowed = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_SMX_VMXON);
+ bool fVmxAllowed = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_VMXON);
+
+ /* Check if the LOCK bit is set but excludes the required VMXON bit. */
+ if (fMsrLocked)
+ {
+ if (fInSmxMode && !fSmxVmxAllowed)
+ rc = VERR_VMX_MSR_SMX_VMXON_DISABLED;
+ else if (!fInSmxMode && !fVmxAllowed)
+ rc = VERR_VMX_MSR_VMXON_DISABLED;
+ else
+ rc = VINF_SUCCESS;
+ }
+ else
+ {
+ /*
+ * MSR is not yet locked; we can change it ourselves here.
+ * Once the lock bit is set, this MSR can no longer be modified.
+ */
+ bool fAllowed;
+ u64FeatMsr |= MSR_IA32_FEATURE_CONTROL_LOCK;
+ if (fInSmxMode)
+ u64FeatMsr |= MSR_IA32_FEATURE_CONTROL_SMX_VMXON;
+ else
+ u64FeatMsr |= MSR_IA32_FEATURE_CONTROL_VMXON;
+
+ ASMWrMsr(MSR_IA32_FEATURE_CONTROL, u64FeatMsr);
+
+ /* Verify. */
+ u64FeatMsr = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+ fMsrLocked = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_LOCK);
+ fSmxVmxAllowed = fMsrLocked && RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_SMX_VMXON);
+ fVmxAllowed = fMsrLocked && RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_VMXON);
+ fAllowed = fInSmxMode ? fSmxVmxAllowed : fVmxAllowed;
+ if (fAllowed)
+ rc = VINF_SUCCESS;
+ else
+ rc = VERR_VMX_MSR_LOCKING_FAILED;
+ }
+
+ if (rc == VINF_SUCCESS)
{
VMX_CAPABILITY vtCaps;
@@ -3242,44 +3481,48 @@ SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps)
if (vtCaps.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_EPT)
*pfCaps |= SUPVTCAPS_NESTED_PAGING;
}
- return VINF_SUCCESS;
}
- return VERR_VMX_MSR_LOCKED_OR_DISABLED;
}
- return VERR_VMX_NO_VMX;
+ else
+ rc = VERR_VMX_NO_VMX;
}
-
- if ( u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX
- && u32VendorECX == X86_CPUID_VENDOR_AMD_ECX
- && u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX
- )
+ else if ( ASMIsAmdCpuEx(uVendorEBX, uVendorECX, uVendorEDX)
+ && ASMIsValidStdRange(uMaxId))
{
- if ( (u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
- && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
- && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
+ uint32_t fExtFeaturesEcx, uExtMaxId;
+ ASMCpuId(0x80000000, &uExtMaxId, &uDummy, &uDummy, &uDummy);
+ ASMCpuId(0x80000001, &uDummy, &uDummy, &fExtFeaturesEcx, &uDummy);
+ if ( ASMIsValidExtRange(uExtMaxId)
+ && uExtMaxId >= 0x8000000a
+ && (fExtFeaturesEcx & X86_CPUID_AMD_FEATURE_ECX_SVM)
+ && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
+ && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
)
{
/* Check if SVM is disabled */
- val = ASMRdMsr(MSR_K8_VM_CR);
- if (!(val & MSR_K8_VM_CR_SVM_DISABLE))
+ u64FeatMsr = ASMRdMsr(MSR_K8_VM_CR);
+ if (!(u64FeatMsr & MSR_K8_VM_CR_SVM_DISABLE))
{
+ uint32_t fSvmFeatures;
*pfCaps |= SUPVTCAPS_AMD_V;
- /* Query AMD features. */
- ASMCpuId(0x8000000A, &u32Dummy, &u32Dummy, &u32Dummy, &u32FeaturesEDX);
-
- if (u32FeaturesEDX & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
+ /* Query AMD-V features. */
+ ASMCpuId(0x8000000a, &uDummy, &uDummy, &uDummy, &fSvmFeatures);
+ if (fSvmFeatures & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
*pfCaps |= SUPVTCAPS_NESTED_PAGING;
- return VINF_SUCCESS;
+ rc = VINF_SUCCESS;
}
- return VERR_SVM_DISABLED;
+ else
+ rc = VERR_SVM_DISABLED;
}
- return VERR_SVM_NO_SVM;
+ else
+ rc = VERR_SVM_NO_SVM;
}
}
- return VERR_UNSUPPORTED_CPU;
+ RTThreadPreemptRestore(&PreemptState);
+ return rc;
}
@@ -4719,7 +4962,7 @@ DECLINLINE(int) supdrvLdrUnlock(PSUPDRVDEVEXT pDevExt)
*/
static int supdrvIOCtl_CallServiceModule(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPCALLSERVICE pReq)
{
-#if !defined(RT_OS_WINDOWS) || defined(DEBUG)
+#if !defined(RT_OS_WINDOWS) || defined(RT_ARCH_AMD64) || defined(DEBUG)
int rc;
/*
@@ -4764,9 +5007,9 @@ static int supdrvIOCtl_CallServiceModule(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION p
Log4(("SUP_IOCTL_CALL_SERVICE: rc=%Rrc op=%u out=%u arg=%RX64 p/t=%RTproc/%RTthrd\n",
rc, pReq->u.In.uOperation, pReq->Hdr.cbOut, pReq->u.In.u64Arg, RTProcSelf(), RTThreadNativeSelf()));
return rc;
-#else /* RT_OS_WINDOWS && !DEBUG */
+#else /* RT_OS_WINDOWS && !RT_ARCH_AMD64 && !DEBUG */
return VERR_NOT_IMPLEMENTED;
-#endif /* RT_OS_WINDOWS && !DEBUG */
+#endif /* RT_OS_WINDOWS && !RT_ARCH_AMD64 && !DEBUG */
}
@@ -4973,7 +5216,7 @@ static int supdrvGipCreate(PSUPDRVDEVEXT pDevExt)
}
}
if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
- rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, 0, supdrvGipSyncTimer, pDevExt);
+ rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, 0 /* fFlags */, supdrvGipSyncTimer, pDevExt);
if (RT_SUCCESS(rc))
{
rc = RTMpNotificationRegister(supdrvGipMpEvent, pDevExt);
@@ -5440,10 +5683,8 @@ static SUPGIPMODE supdrvGipDeterminTscMode(PSUPDRVDEVEXT pDevExt)
*/
/* Check for "AuthenticAMD" */
ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
- if ( uEAX >= 1
- && uEBX == X86_CPUID_VENDOR_AMD_EBX
- && uECX == X86_CPUID_VENDOR_AMD_ECX
- && uEDX == X86_CPUID_VENDOR_AMD_EDX)
+ if ( uEAX >= 1
+ && ASMIsAmdCpuEx(uEBX, uECX, uEDX))
{
/* Check for APM support and that TscInvariant is cleared. */
ASMCpuId(0x80000000, &uEAX, &uEBX, &uECX, &uEDX);
@@ -5835,3 +6076,18 @@ static void supdrvGipUpdatePerCpu(PSUPDRVDEVEXT pDevExt, uint64_t u64NanoTS, uin
}
}
+/**
+ * Resume built-in keyboard on MacBook Air and Pro hosts.
+ * If there is no built-in keyboard device, return success anyway.
+ *
+ * @returns 0 on Mac OS X platform, VERR_NOT_IMPLEMENTED on the other ones.
+ */
+static int supdrvIOCtl_ResumeSuspendedKbds(void)
+{
+#if defined(RT_OS_DARWIN)
+ return supdrvDarwinResumeSuspendedKbds();
+#else
+ return VERR_NOT_IMPLEMENTED;
+#endif
+}
+
diff --git a/src/VBox/HostDrivers/Support/SUPDrvIDC.h b/src/VBox/HostDrivers/Support/SUPDrvIDC.h
index ca9fe314..7de0224e 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvIDC.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvIDC.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -224,7 +224,11 @@ typedef SUPDRVIDCREQCOMPDEREGFACTORY *PSUPDRVIDCREQCOMPDEREGFACTORY;
RT_C_DECLS_BEGIN
#if defined(RT_OS_DARWIN)
-extern int VBOXCALL SUPDrvDarwinIDC(uint32_t iReq, PSUPDRVIDCREQHDR pReq);
+# ifdef IN_SUP_R0
+extern DECLEXPORT(int) VBOXCALL SUPDrvDarwinIDC(uint32_t iReq, PSUPDRVIDCREQHDR pReq);
+# else
+extern DECLIMPORT(int) VBOXCALL SUPDrvDarwinIDC(uint32_t iReq, PSUPDRVIDCREQHDR pReq);
+# endif
#elif defined(RT_OS_FREEBSD)
extern int VBOXCALL SUPDrvFreeBSDIDC(uint32_t iReq, PSUPDRVIDCREQHDR pReq);
diff --git a/src/VBox/HostDrivers/Support/SUPDrvIOC.h b/src/VBox/HostDrivers/Support/SUPDrvIOC.h
index dceca008..6d19ebc2 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvIOC.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvIOC.h
@@ -1,10 +1,10 @@
-/* $Revision: 78601 $ */
+/* $Revision: 91386 $ */
/** @file
* VirtualBox Support Driver - IOCtl definitions.
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -100,8 +100,8 @@
/** Fast path IOCtl: VMMR0_DO_RAW_RUN */
#define SUP_IOCTL_FAST_DO_RAW_RUN SUP_CTL_CODE_FAST(64)
-/** Fast path IOCtl: VMMR0_DO_HWACC_RUN */
-#define SUP_IOCTL_FAST_DO_HWACC_RUN SUP_CTL_CODE_FAST(65)
+/** Fast path IOCtl: VMMR0_DO_HM_RUN */
+#define SUP_IOCTL_FAST_DO_HM_RUN SUP_CTL_CODE_FAST(65)
/** Just a NOP call for profiling the latency of a fast ioctl call to VMMR0. */
#define SUP_IOCTL_FAST_DO_NOP SUP_CTL_CODE_FAST(66)
@@ -193,7 +193,7 @@ typedef SUPREQHDR *PSUPREQHDR;
* @todo Pending work on next major version change:
* - Remove RTSpinlockReleaseNoInts.
*/
-#define SUPDRV_IOC_VERSION 0x001a0004
+#define SUPDRV_IOC_VERSION 0x001a0007
/** SUP_IOCTL_COOKIE. */
typedef struct SUPCOOKIE
@@ -1332,6 +1332,18 @@ typedef struct SUPTRACERUMODFIREPROBE
/** @} */
+/** @name SUP_IOCTL_RESUME_SUSPENDED_KBDS
+ * Resume suspended keyboard devices if any found in the system.
+ *
+ * @{
+ */
+#define SUP_IOCTL_RESUME_SUSPENDED_KBDS SUP_CTL_CODE_SIZE(35, SUP_IOCTL_RESUME_SUSPENDED_KBDS_SIZE)
+#define SUP_IOCTL_RESUME_SUSPENDED_KBDS_SIZE sizeof(SUPREQHDR)
+#define SUP_IOCTL_RESUME_SUSPENDED_KBDS_SIZE_IN sizeof(SUPREQHDR)
+#define SUP_IOCTL_RESUME_SUSPENDED_KBDS_SIZE_OUT sizeof(SUPREQHDR)
+/** @} */
+
+
#pragma pack() /* paranoia */
#endif
diff --git a/src/VBox/HostDrivers/Support/SUPDrvInternal.h b/src/VBox/HostDrivers/Support/SUPDrvInternal.h
index bc914982..cca6c30a 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvInternal.h
@@ -1,10 +1,10 @@
-/* $Revision: 80003 $ */
+/* $Id: SUPDrvInternal.h $ */
/** @file
* VirtualBox Support Driver - Internal header.
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -199,6 +199,16 @@
( VALID_PTR(pSession) \
&& pSession->u32Cookie == BIRD_INV)
+/**
+ * Validates a device extension pointer.
+ *
+ * @returns true/false accordingly.
+ * @param pDevExt The device extension.
+ */
+#define SUP_IS_DEVEXT_VALID(pDevExt) \
+ ( VALID_PTR(pDevExt)\
+ && pDevExt->u32Cookie == BIRD)
+
/*******************************************************************************
* Structures and Typedefs *
@@ -378,9 +388,9 @@ typedef struct SUPDRVOBJ
} SUPDRVOBJ, *PSUPDRVOBJ;
/** Magic number for SUPDRVOBJ::u32Magic. (Dame Agatha Mary Clarissa Christie). */
-#define SUPDRVOBJ_MAGIC 0x18900915
+#define SUPDRVOBJ_MAGIC UINT32_C(0x18900915)
/** Dead number magic for SUPDRVOBJ::u32Magic. */
-#define SUPDRVOBJ_MAGIC_DEAD 0x19760112
+#define SUPDRVOBJ_MAGIC_DEAD UINT32_C(0x19760112)
/**
* The per-session object usage record.
@@ -406,11 +416,15 @@ typedef struct SUPDRVSESSION
PSUPDRVDEVEXT pDevExt;
/** Session Cookie. */
uint32_t u32Cookie;
+ /** Set if is an unrestricted session, clear if restricted. */
+ bool fUnrestricted;
+ /* Reference counter. */
+ uint32_t volatile cRefs;
/** The VM associated with the session. */
PVM pVM;
/** Handle table for IPRT semaphore wrapper APIs.
- * Programmable from R0 and R3. */
+ * This takes care of its own locking in an IRQ safe manner. */
RTHANDLETABLE hHandleTable;
/** Load usage records. (protected by SUPDRVDEVEXT::mtxLdr) */
PSUPDRVLDRUSAGE volatile pLdrUsage;
@@ -476,7 +490,15 @@ typedef struct SUPDRVSESSION
*/
typedef struct SUPDRVDEVEXT
{
- /** Spinlock to serialize the initialization, usage counting and objects. */
+ /** Global cookie. */
+ uint32_t u32Cookie;
+ /** The actual size of SUPDRVSESSION. (SUPDRV_AGNOSTIC) */
+ uint32_t cbSession;
+
+ /** Spinlock to serialize the initialization, usage counting and objects.
+ * This is IRQ safe because we want to be able signal semaphores from the
+ * special HM context (and later maybe interrupt handlers), so we must be able
+ * to reference and dereference handles when IRQs are disabled. */
RTSPINLOCK Spinlock;
/** List of registered objects. Protected by the spinlock. */
@@ -484,11 +506,6 @@ typedef struct SUPDRVDEVEXT
/** List of free object usage records. */
PSUPDRVUSAGE volatile pUsageFree;
- /** Global cookie. */
- uint32_t u32Cookie;
- /** The actual size of SUPDRVSESSION. (SUPDRV_AGNOSTIC) */
- uint32_t cbSession;
-
/** Loader mutex.
* This protects pvVMMR0, pvVMMR0Entry, pImages and SUPDRVSESSION::pLdrUsage. */
#ifdef SUPDRV_USE_MUTEX_FOR_LDR
@@ -529,7 +546,9 @@ typedef struct SUPDRVDEVEXT
#else
RTSEMFASTMUTEX mtxGip;
#endif
- /** GIP spinlock protecting GIP members during Mp events. */
+ /** GIP spinlock protecting GIP members during Mp events.
+ * This is IRQ safe since be may get MP callbacks in contexts where IRQs are
+ * disabled (on some platforms). */
RTSPINLOCK hGipSpinlock;
/** Pointer to the Global Info Page (GIP). */
PSUPGLOBALINFOPAGE pGip;
@@ -600,6 +619,8 @@ void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc);
bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt);
int VBOXCALL supdrvOSEnableVTx(bool fEnabled);
+bool VBOXCALL supdrvOSSuspendVTxOnCpu(void);
+void VBOXCALL supdrvOSResumeVTxOnCpu(bool fSuspended);
/**
* Try open the image using the native loader.
@@ -663,6 +684,11 @@ int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, c
void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage);
+#if defined(RT_OS_DARWIN)
+int VBOXCALL supdrvDarwinResumeSuspendedKbds(void);
+#endif
+
+
/*******************************************************************************
* Shared Functions *
*******************************************************************************/
@@ -672,9 +698,9 @@ int VBOXCALL supdrvIOCtlFast(uintptr_t uIOCtl, VMCPUID idCpu, PSUPDRVDEVEXT p
int VBOXCALL supdrvIDC(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPDRVIDCREQHDR pReqHdr);
int VBOXCALL supdrvInitDevExt(PSUPDRVDEVEXT pDevExt, size_t cbSession);
void VBOXCALL supdrvDeleteDevExt(PSUPDRVDEVEXT pDevExt);
-int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, PSUPDRVSESSION *ppSession);
-void VBOXCALL supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
-void VBOXCALL supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
+int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted, PSUPDRVSESSION *ppSession);
+uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession);
+uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession);
int VBOXCALL supdrvTracerInit(PSUPDRVDEVEXT pDevExt);
void VBOXCALL supdrvTracerTerm(PSUPDRVDEVEXT pDevExt);
diff --git a/src/VBox/HostDrivers/Support/SUPDrvSem.c b/src/VBox/HostDrivers/Support/SUPDrvSem.c
index f546f56f..142cfa7a 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvSem.c
+++ b/src/VBox/HostDrivers/Support/SUPDrvSem.c
@@ -1,10 +1,10 @@
-/* $Revision: 66703 $ */
+/* $Revision: 83575 $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Common OS agnostic.
*/
/*
- * Copyright (C) 2006-2009 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPDrvTracer.cpp b/src/VBox/HostDrivers/Support/SUPDrvTracer.cpp
index 45c622ef..373b2693 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvTracer.cpp
+++ b/src/VBox/HostDrivers/Support/SUPDrvTracer.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2012 Oracle Corporation
+ * Copyright (C) 2012-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -345,7 +345,9 @@ static int supdrvVtgValidateHdr(PVTGOBJHDR pVtgHdr, RTUINTPTR uVtgHdrAddr, const
#ifdef RT_OS_DARWIN
/* The loader and/or ld64-97.17 seems not to generate fixups for our
__VTGObj section. Detect this by comparing them with the
- u64VtgObjSectionStart member and assume max image size of 4MB. */
+ u64VtgObjSectionStart member and assume max image size of 4MB.
+ Seems to be worked around by the __VTGPrLc.End and __VTGPrLc.Begin
+ padding fudge, meaning that the linker misplaced the relocations. */
if ( (int64_t)u64Tmp != (int32_t)u64Tmp
&& pVtgHdr->u64VtgObjSectionStart != uVtgHdrAddr
&& pVtgHdr->u64VtgObjSectionStart < _4M
@@ -635,7 +637,6 @@ static int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, RTUINTPTR uVtgHdrAddr, const ui
MY_CHECK_RET(paProbeLocs[i].uLine < _1G, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
MY_CHECK_RET(paProbeLocs[i].fEnabled == false, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
MY_CHECK_RET(paProbeLocs[i].idProbe == 0, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
- MY_WITHIN_IMAGE(paProbeLocs[i].pszFunction, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
offTmp = (uintptr_t)paProbeLocs[i].pProbe - (uintptr_t)pVtgHdr->offProbes - (uintptr_t)pVtgHdr;
#ifdef RT_OS_DARWIN /* See header validation code. */
if ( offTmp >= pVtgHdr->cbProbes
@@ -645,12 +646,17 @@ static int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, RTUINTPTR uVtgHdrAddr, const ui
&& !fUmod )
{
uint64_t offDelta = uVtgHdrAddr - pVtgHdr->u64VtgObjSectionStart;
+
paProbeLocs[i].pProbe = (PVTGDESCPROBE)((uintptr_t)paProbeLocs[i].pProbe + offDelta);
+ if ((uintptr_t)paProbeLocs[i].pszFunction < _4M)
+ paProbeLocs[i].pszFunction = (const char *)((uintptr_t)paProbeLocs[i].pszFunction + offDelta);
+
offTmp += offDelta;
}
#endif
MY_CHECK_RET(offTmp < pVtgHdr->cbProbes, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
MY_CHECK_RET(offTmp / sizeof(VTGDESCPROBE) * sizeof(VTGDESCPROBE) == offTmp, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
+ MY_WITHIN_IMAGE(paProbeLocs[i].pszFunction, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
}
}
@@ -1466,13 +1472,13 @@ SUPR0TracerFireProbe: \n\
");
# if defined(RT_ARCH_AMD64)
__asm__(" \
- movq g_pfnSupdrvProbeFireKernel(%rip), %rax \n\
- jmp *%rax \n\
+ movq g_pfnSupdrvProbeFireKernel(%rip), %rax \n\
+ jmp *%rax \n\
");
# elif defined(RT_ARCH_X86)
__asm__("\
- movl g_pfnSupdrvProbeFireKernel, %eax \n\
- jmp *%eax \n\
+ movl g_pfnSupdrvProbeFireKernel, %eax \n\
+ jmp *%eax \n\
");
# else
# error "Which arch is this?"
@@ -2132,6 +2138,7 @@ int VBOXCALL supdrvIOCtl_TracerUmodDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVS
RTR0MemObjFree(pUmod->hMemObjMap, false /*fFreeMappings*/);
RTR0MemObjFree(pUmod->hMemObjLock, false /*fFreeMappings*/);
RTMemFree(pUmod);
+ rc = VINF_SUCCESS;
}
else
rc = VERR_NOT_FOUND;
diff --git a/src/VBox/HostDrivers/Support/SUPLib.cpp b/src/VBox/HostDrivers/Support/SUPLib.cpp
index c7878bcd..d408bf2a 100644
--- a/src/VBox/HostDrivers/Support/SUPLib.cpp
+++ b/src/VBox/HostDrivers/Support/SUPLib.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -97,11 +97,12 @@ static bool g_fPreInited = false;
* via the pre-init mechanism from the hardened executable stub. */
SUPLIBDATA g_supLibData =
{
- SUP_HDEVICE_NIL
+ /*.hDevice = */ SUP_HDEVICE_NIL,
+ /*.fUnrestricted = */ true
#if defined(RT_OS_DARWIN)
- , NULL
+ ,/* .uConnection = */ NULL
#elif defined(RT_OS_LINUX)
- , false
+ ,/* .fSysMadviseWorks = */ false
#endif
};
@@ -209,7 +210,7 @@ DECLEXPORT(int) supR3PreInit(PSUPPREINITDATA pPreInitData, uint32_t fFlags)
}
-SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
+SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession)
{
/*
* Perform some sanity checks.
@@ -228,7 +229,16 @@ SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
if (ppSession)
*ppSession = g_pSession;
if (g_cInits++ > 0)
+ {
+ if (fUnrestricted && !g_supLibData.fUnrestricted)
+ {
+ g_cInits--;
+ if (ppSession)
+ *ppSession = NIL_RTR0PTR;
+ return VERR_VM_DRIVER_NOT_ACCESSIBLE; /** @todo different status code? */
+ }
return VINF_SUCCESS;
+ }
/*
* Check for fake mode.
@@ -251,7 +261,7 @@ SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
/*
* Open the support driver.
*/
- int rc = suplibOsInit(&g_supLibData, g_fPreInited);
+ int rc = suplibOsInit(&g_supLibData, g_fPreInited, fUnrestricted);
if (RT_SUCCESS(rc))
{
/*
@@ -267,8 +277,8 @@ SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
CookieReq.Hdr.rc = VERR_INTERNAL_ERROR;
strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
- const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00190000
- ? 0x00190003
+ const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x001a0000
+ ? 0x001a0005
: SUPDRV_IOC_VERSION & 0xffff0000;
CookieReq.u.In.u32MinVersion = uMinVersion;
rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_COOKIE, &CookieReq, SUP_IOCTL_COOKIE_SIZE);
@@ -281,64 +291,75 @@ SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
/*
* Query the functions.
*/
- PSUPQUERYFUNCS pFuncsReq = (PSUPQUERYFUNCS)RTMemAllocZ(SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
- if (pFuncsReq)
+ PSUPQUERYFUNCS pFuncsReq = NULL;
+ if (g_supLibData.fUnrestricted)
{
- pFuncsReq->Hdr.u32Cookie = CookieReq.u.Out.u32Cookie;
- pFuncsReq->Hdr.u32SessionCookie = CookieReq.u.Out.u32SessionCookie;
- pFuncsReq->Hdr.cbIn = SUP_IOCTL_QUERY_FUNCS_SIZE_IN;
- pFuncsReq->Hdr.cbOut = SUP_IOCTL_QUERY_FUNCS_SIZE_OUT(CookieReq.u.Out.cFunctions);
- pFuncsReq->Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
- pFuncsReq->Hdr.rc = VERR_INTERNAL_ERROR;
- rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_QUERY_FUNCS(CookieReq.u.Out.cFunctions), pFuncsReq, SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
- if (RT_SUCCESS(rc))
- rc = pFuncsReq->Hdr.rc;
- if (RT_SUCCESS(rc))
+ pFuncsReq = (PSUPQUERYFUNCS)RTMemAllocZ(SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
+ if (pFuncsReq)
{
- /*
- * Map the GIP into userspace.
- */
- Assert(!g_pSUPGlobalInfoPage);
- SUPGIPMAP GipMapReq;
- GipMapReq.Hdr.u32Cookie = CookieReq.u.Out.u32Cookie;
- GipMapReq.Hdr.u32SessionCookie = CookieReq.u.Out.u32SessionCookie;
- GipMapReq.Hdr.cbIn = SUP_IOCTL_GIP_MAP_SIZE_IN;
- GipMapReq.Hdr.cbOut = SUP_IOCTL_GIP_MAP_SIZE_OUT;
- GipMapReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
- GipMapReq.Hdr.rc = VERR_INTERNAL_ERROR;
- GipMapReq.u.Out.HCPhysGip = NIL_RTHCPHYS;
- GipMapReq.u.Out.pGipR0 = NIL_RTR0PTR;
- GipMapReq.u.Out.pGipR3 = NULL;
- rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_GIP_MAP, &GipMapReq, SUP_IOCTL_GIP_MAP_SIZE);
+ pFuncsReq->Hdr.u32Cookie = CookieReq.u.Out.u32Cookie;
+ pFuncsReq->Hdr.u32SessionCookie = CookieReq.u.Out.u32SessionCookie;
+ pFuncsReq->Hdr.cbIn = SUP_IOCTL_QUERY_FUNCS_SIZE_IN;
+ pFuncsReq->Hdr.cbOut = SUP_IOCTL_QUERY_FUNCS_SIZE_OUT(CookieReq.u.Out.cFunctions);
+ pFuncsReq->Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
+ pFuncsReq->Hdr.rc = VERR_INTERNAL_ERROR;
+ rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_QUERY_FUNCS(CookieReq.u.Out.cFunctions), pFuncsReq,
+ SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
if (RT_SUCCESS(rc))
- rc = GipMapReq.Hdr.rc;
+ rc = pFuncsReq->Hdr.rc;
if (RT_SUCCESS(rc))
{
- AssertRelease(GipMapReq.u.Out.pGipR3->u32Magic == SUPGLOBALINFOPAGE_MAGIC);
- AssertRelease(GipMapReq.u.Out.pGipR3->u32Version >= SUPGLOBALINFOPAGE_VERSION);
-
/*
- * Set the globals and return success.
+ * Map the GIP into userspace.
*/
- ASMAtomicXchgSize(&g_HCPhysSUPGlobalInfoPage, GipMapReq.u.Out.HCPhysGip);
- ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPage, GipMapReq.u.Out.pGipR3, NULL);
- ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPageR0, (void *)GipMapReq.u.Out.pGipR0, NULL);
-
- g_u32Cookie = CookieReq.u.Out.u32Cookie;
- g_u32SessionCookie = CookieReq.u.Out.u32SessionCookie;
- g_pSession = CookieReq.u.Out.pSession;
- g_pFunctions = pFuncsReq;
- if (ppSession)
- *ppSession = CookieReq.u.Out.pSession;
- return VINF_SUCCESS;
+ Assert(!g_pSUPGlobalInfoPage);
+ SUPGIPMAP GipMapReq;
+ GipMapReq.Hdr.u32Cookie = CookieReq.u.Out.u32Cookie;
+ GipMapReq.Hdr.u32SessionCookie = CookieReq.u.Out.u32SessionCookie;
+ GipMapReq.Hdr.cbIn = SUP_IOCTL_GIP_MAP_SIZE_IN;
+ GipMapReq.Hdr.cbOut = SUP_IOCTL_GIP_MAP_SIZE_OUT;
+ GipMapReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
+ GipMapReq.Hdr.rc = VERR_INTERNAL_ERROR;
+ GipMapReq.u.Out.HCPhysGip = NIL_RTHCPHYS;
+ GipMapReq.u.Out.pGipR0 = NIL_RTR0PTR;
+ GipMapReq.u.Out.pGipR3 = NULL;
+ rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_GIP_MAP, &GipMapReq, SUP_IOCTL_GIP_MAP_SIZE);
+ if (RT_SUCCESS(rc))
+ rc = GipMapReq.Hdr.rc;
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Set the GIP globals.
+ */
+ AssertRelease(GipMapReq.u.Out.pGipR3->u32Magic == SUPGLOBALINFOPAGE_MAGIC);
+ AssertRelease(GipMapReq.u.Out.pGipR3->u32Version >= SUPGLOBALINFOPAGE_VERSION);
+
+ ASMAtomicXchgSize(&g_HCPhysSUPGlobalInfoPage, GipMapReq.u.Out.HCPhysGip);
+ ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPage, GipMapReq.u.Out.pGipR3, NULL);
+ ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPageR0, (void *)GipMapReq.u.Out.pGipR0, NULL);
+ }
}
}
+ else
+ rc = VERR_NO_MEMORY;
+ }
- /* bailout */
- RTMemFree(pFuncsReq);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Set the globals and return success.
+ */
+ g_u32Cookie = CookieReq.u.Out.u32Cookie;
+ g_u32SessionCookie = CookieReq.u.Out.u32SessionCookie;
+ g_pSession = CookieReq.u.Out.pSession;
+ g_pFunctions = pFuncsReq;
+ if (ppSession)
+ *ppSession = CookieReq.u.Out.pSession;
+ return VINF_SUCCESS;
}
- else
- rc = VERR_NO_MEMORY;
+
+ /* bailout */
+ RTMemFree(pFuncsReq);
}
else
{
@@ -372,6 +393,12 @@ SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
return rc;
}
+
+SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
+{
+ return SUPR3InitEx(true, ppSession);
+}
+
/**
* Fake mode init.
*/
@@ -590,8 +617,8 @@ SUPR3DECL(int) SUPR3CallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, VMCPUID idCp
NOREF(pVMR0);
if (RT_LIKELY(uOperation == SUP_VMMR0_DO_RAW_RUN))
return suplibOsIOCtlFast(&g_supLibData, SUP_IOCTL_FAST_DO_RAW_RUN, idCpu);
- if (RT_LIKELY(uOperation == SUP_VMMR0_DO_HWACC_RUN))
- return suplibOsIOCtlFast(&g_supLibData, SUP_IOCTL_FAST_DO_HWACC_RUN, idCpu);
+ if (RT_LIKELY(uOperation == SUP_VMMR0_DO_HM_RUN))
+ return suplibOsIOCtlFast(&g_supLibData, SUP_IOCTL_FAST_DO_HM_RUN, idCpu);
if (RT_LIKELY(uOperation == SUP_VMMR0_DO_NOP))
return suplibOsIOCtlFast(&g_supLibData, SUP_IOCTL_FAST_DO_NOP, idCpu);
@@ -606,7 +633,7 @@ SUPR3DECL(int) SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation,
* The following operations don't belong here.
*/
AssertMsgReturn( uOperation != SUP_VMMR0_DO_RAW_RUN
- && uOperation != SUP_VMMR0_DO_HWACC_RUN
+ && uOperation != SUP_VMMR0_DO_HM_RUN
&& uOperation != SUP_VMMR0_DO_NOP,
("%#x\n", uOperation),
VERR_INTERNAL_ERROR);
@@ -693,7 +720,7 @@ SUPR3DECL(int) SUPR3CallVMMR0(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, v
* The following operations don't belong here.
*/
AssertMsgReturn( uOperation != SUP_VMMR0_DO_RAW_RUN
- && uOperation != SUP_VMMR0_DO_HWACC_RUN
+ && uOperation != SUP_VMMR0_DO_HM_RUN
&& uOperation != SUP_VMMR0_DO_NOP,
("%#x\n", uOperation),
VERR_INTERNAL_ERROR);
@@ -1578,7 +1605,7 @@ SUPR3DECL(int) SUPR3LoadModule(const char *pszFilename, const char *pszModule, v
{
rc = supLoadModule(pszFilename, pszModule, NULL, ppvImageBase);
if (RT_FAILURE(rc))
- RTErrInfoSetF(pErrInfo, rc, "supLoadModule returned %Rrc", rc);
+ RTErrInfoSetF(pErrInfo, rc, "SUPR3LoadModule: supLoadModule returned %Rrc", rc);
}
return rc;
}
@@ -1645,7 +1672,7 @@ static DECLCALLBACK(int) supLoadModuleResolveImport(RTLDRMOD hLdrMod, const char
*/
/** @todo is this actually used??? */
/* skip the 64-bit ELF import prefix first. */
- if (!strncmp(pszSymbol, "SUPR0$", sizeof("SUPR0$") - 1))
+ if (!strncmp(pszSymbol, RT_STR_TUPLE("SUPR0$")))
pszSymbol += sizeof("SUPR0$") - 1;
/*
@@ -1826,7 +1853,10 @@ static int supLoadModule(const char *pszFilename, const char *pszModule, const c
RTLDRMOD hLdrMod;
rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_HOST, &hLdrMod);
if (!RT_SUCCESS(rc))
+ {
+ LogRel(("SUP: RTLdrOpen failed for %s (%s)\n", pszModule, pszFilename, rc));
return rc;
+ }
SUPLDRCALCSIZEARGS CalcArgs;
CalcArgs.cbStrings = 0;
@@ -1971,6 +2001,8 @@ static int supLoadModule(const char *pszFilename, const char *pszModule, const c
rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_LOAD, pLoadReq, SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithTabs));
if (RT_SUCCESS(rc))
rc = pLoadReq->Hdr.rc;
+ else
+ LogRel(("SUP: SUP_IOCTL_LDR_LOAD ioctl for %s (%s) failed rc=%Rrc\n", pszModule, pszFilename, rc));
}
else
rc = VINF_SUCCESS;
@@ -1995,9 +2027,17 @@ static int supLoadModule(const char *pszFilename, const char *pszModule, const c
RTLdrClose(hLdrMod);
return VINF_SUCCESS;
}
+ else
+ LogRel(("SUP: Loading failed for %s (%s) rc=%Rrc\n", pszModule, pszFilename, rc));
}
+ else
+ LogRel(("SUP: RTLdrEnumSymbols failed for %s (%s) rc=%Rrc\n", pszModule, pszFilename, rc));
}
+ else
+ LogRel(("SUP: Failed to get entry points for %s (%s) rc=%Rrc\n", pszModule, pszFilename, rc));
}
+ else
+ LogRel(("SUP: RTLdrGetBits failed for %s (%s). rc=%Rrc\n", pszModule, pszFilename, rc));
RTMemTmpFree(pLoadReq);
}
else
@@ -2701,3 +2741,26 @@ DECLASM(void) suplibTracerFireProbe(PVTGPROBELOC pProbeLoc, PSUPTRACERUMODFIREPR
suplibOsIOCtl(&g_supLibData, SUP_IOCTL_TRACER_UMOD_FIRE_PROBE, pReq, SUP_IOCTL_TRACER_UMOD_FIRE_PROBE_SIZE);
}
+
+SUPR3DECL(int) SUPR3ResumeSuspendedKeyboards(void)
+{
+#ifdef RT_OS_DARWIN
+ /*
+ * Issue IOCtl to the SUPDRV kernel module.
+ */
+ SUPREQHDR Req;
+ Req.u32Cookie = g_u32Cookie;
+ Req.u32SessionCookie= g_u32SessionCookie;
+ Req.cbIn = SUP_IOCTL_RESUME_SUSPENDED_KBDS_SIZE_IN;
+ Req.cbOut = SUP_IOCTL_RESUME_SUSPENDED_KBDS_SIZE_OUT;
+ Req.fFlags = SUPREQHDR_FLAGS_DEFAULT;
+ Req.rc = VERR_INTERNAL_ERROR;
+ int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_RESUME_SUSPENDED_KBDS, &Req, SUP_IOCTL_RESUME_SUSPENDED_KBDS_SIZE);
+ if (RT_SUCCESS(rc))
+ rc = Req.rc;
+ return rc;
+#else /* !RT_OS_DARWIN */
+ return VERR_NOT_SUPPORTED;
+#endif
+}
+
diff --git a/src/VBox/HostDrivers/Support/SUPLibInternal.h b/src/VBox/HostDrivers/Support/SUPLibInternal.h
index 0f37d7b7..bb186beb 100644
--- a/src/VBox/HostDrivers/Support/SUPLibInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPLibInternal.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -189,6 +189,9 @@ typedef struct SUPLIBDATA
#else
int hDevice;
#endif
+ /** Indicates whether we have unrestricted (true) or restricted access to the
+ * support device. */
+ bool fUnrestricted;
#if defined(RT_OS_DARWIN)
/** The connection to the VBoxSupDrv service. */
uintptr_t uConnection;
@@ -263,7 +266,7 @@ extern DECLHIDDEN(SUPLIBDATA) g_supLibData;
RT_C_DECLS_BEGIN
int suplibOsInstall(void);
int suplibOsUninstall(void);
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited);
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted);
int suplibOsTerm(PSUPLIBDATA pThis);
int suplibOsIOCtl(PSUPLIBDATA pThis, uintptr_t uFunction, void *pvReq, size_t cbReq);
int suplibOsIOCtlFast(PSUPLIBDATA pThis, uintptr_t uFunction, uintptr_t idCpu);
diff --git a/src/VBox/HostDrivers/Support/SUPLibSem.cpp b/src/VBox/HostDrivers/Support/SUPLibSem.cpp
index e835f599..7df18916 100644
--- a/src/VBox/HostDrivers/Support/SUPLibSem.cpp
+++ b/src/VBox/HostDrivers/Support/SUPLibSem.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPLibTracerA.asm b/src/VBox/HostDrivers/Support/SUPLibTracerA.asm
index a6ab1969..c77881c2 100644
--- a/src/VBox/HostDrivers/Support/SUPLibTracerA.asm
+++ b/src/VBox/HostDrivers/Support/SUPLibTracerA.asm
@@ -102,49 +102,49 @@ EXPORTEDNAME SUPTracerFireProbe
pushf
pop xAX
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.rflags], xAX
- mov xAX, [xBP + xS]
+ mov xAX, [xBP + xCB]
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.rip], xAX
mov xAX, [xBP]
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.rbp], xAX
- lea xAX, [xBP + xS*2]
+ lea xAX, [xBP + xCB*2]
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.rsp], xAX
%ifdef ASM_CALL64_MSC
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.uVtgProbeLoc], rcx
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*0], rdx
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*1], r8
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*2], r9
- mov xAX, [xBP + xS*2 + 0x20 + xS*0]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*3], xAX
- mov xAX, [xBP + xS*2 + 0x20 + xS*1]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*4], xAX
- mov xAX, [xBP + xS*2 + 0x20 + xS*2]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*5], xAX
- mov xAX, [xBP + xS*2 + 0x20 + xS*3]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*6], xAX
- mov xAX, [xBP + xS*2 + 0x20 + xS*4]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*7], xAX
- mov xAX, [xBP + xS*2 + 0x20 + xS*5]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*8], xAX
- mov xAX, [xBP + xS*2 + 0x20 + xS*6]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*9], xAX
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*0], rdx
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*1], r8
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*2], r9
+ mov xAX, [xBP + xCB*2 + 0x20 + xCB*0]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*3], xAX
+ mov xAX, [xBP + xCB*2 + 0x20 + xCB*1]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*4], xAX
+ mov xAX, [xBP + xCB*2 + 0x20 + xCB*2]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*5], xAX
+ mov xAX, [xBP + xCB*2 + 0x20 + xCB*3]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*6], xAX
+ mov xAX, [xBP + xCB*2 + 0x20 + xCB*4]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*7], xAX
+ mov xAX, [xBP + xCB*2 + 0x20 + xCB*5]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*8], xAX
+ mov xAX, [xBP + xCB*2 + 0x20 + xCB*6]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*9], xAX
mov eax, [xCX + 4] ; VTGPROBELOC::idProbe.
%else
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.uVtgProbeLoc], rdi
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*0], rsi
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*1], rdx
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*2], rcx
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*3], r8
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*4], r9
- mov xAX, [xBP + xS*2 + xS*0]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*5], xAX
- mov xAX, [xBP + xS*2 + xS*1]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*6], xAX
- mov xAX, [xBP + xS*2 + xS*2]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*7], xAX
- mov xAX, [xBP + xS*2 + xS*3]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*8], xAX
- mov xAX, [xBP + xS*2 + xS*4]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xS*9], xAX
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*0], rsi
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*1], rdx
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*2], rcx
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*3], r8
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*4], r9
+ mov xAX, [xBP + xCB*2 + xCB*0]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*5], xAX
+ mov xAX, [xBP + xCB*2 + xCB*1]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*6], xAX
+ mov xAX, [xBP + xCB*2 + xCB*2]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*7], xAX
+ mov xAX, [xBP + xCB*2 + xCB*3]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*8], xAX
+ mov xAX, [xBP + xCB*2 + xCB*4]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.u.Amd64.aArgs + xCB*9], xAX
mov eax, [xDI + 4] ; VTGPROBELOC::idProbe.
%endif
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX64.idProbe], eax
@@ -179,21 +179,21 @@ EXPORTEDNAME SUPTracerFireProbe
pushf
pop xAX
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX32.u.X86.eflags], xAX
- mov xAX, [xBP + xS]
+ mov xAX, [xBP + xCB]
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX32.u.X86.eip], xAX
mov xAX, [xBP]
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX32.u.X86.ebp], xAX
- lea xAX, [xBP + xS*2]
+ lea xAX, [xBP + xCB*2]
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX32.u.X86.esp], xAX
- mov xCX, [xBP + xS*2 + xS*0]
+ mov xCX, [xBP + xCB*2 + xCB*0]
mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX32.u.X86.uVtgProbeLoc], xCX ; keep, used below.
mov edx, 20
.more:
dec edx
- mov xAX, [xBP + xS*2 + xS*xDX]
- mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX32.u.X86.aArgs + xS*xDX], xAX
+ mov xAX, [xBP + xCB*2 + xCB*xDX]
+ mov [xSP + SUPTRACERUMODFIREPROBE.In + SUPDRVTRACERUSRCTX32.u.X86.aArgs + xCB*xDX], xAX
jnz .more
mov eax, [xCX + 4] ; VTGPROBELOC::idProbe.
diff --git a/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c b/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c
index d867a37e..43926072 100644
--- a/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c
+++ b/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h b/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h
index 29ada07f..dc165dde 100644
--- a/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c b/src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c
index 595d2474..0bccc5f7 100644
--- a/src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c
+++ b/src/VBox/HostDrivers/Support/SUPR0IdcClientStubs.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp
index 3b5c08e8..ef00d485 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedIPRT.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
index ec64e52a..16ca4647 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -577,7 +577,7 @@ static size_t supR3HardenedStrPrintf(char *pszDst, size_t cchDst, const char *ps
*/
static void supR3HardenedMainOpenDevice(void)
{
- int rc = suplibOsInit(&g_SupPreInitData.Data, false);
+ int rc = suplibOsInit(&g_SupPreInitData.Data, false /*fPreInit*/, true /*fUnrestricted*/);
if (RT_SUCCESS(rc))
return;
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
index 01a80368..5229fb1a 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -186,11 +186,6 @@ static SUPINSTFILE const g_aSupInstallFiles[] =
{ kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxSDL" SUPLIB_DLL_SUFF },
//#endif
-//#ifdef VBOX_WITH_VBOXBFE
- { kSupIFT_Exe, kSupID_AppBin, true, "VBoxBFE" SUPLIB_EXE_SUFF },
- { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxBFE" SUPLIB_DLL_SUFF },
-//#endif
-
//#ifdef VBOX_WITH_WEBSERVICES
{ kSupIFT_Exe, kSupID_AppBin, true, "vboxwebsrv" SUPLIB_EXE_SUFF },
//#endif
@@ -203,6 +198,11 @@ static SUPINSTFILE const g_aSupInstallFiles[] =
{ kSupIFT_Exe, kSupID_AppBin, true, "VBoxNetDHCP" SUPLIB_EXE_SUFF },
{ kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxNetDHCP" SUPLIB_DLL_SUFF },
//#endif
+
+//#ifdef VBOX_WITH_LWIP_NAT
+ { kSupIFT_Exe, kSupID_AppBin, true, "VBoxNetNAT" SUPLIB_EXE_SUFF },
+ { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxNetNAT" SUPLIB_DLL_SUFF },
+//#endif
};
diff --git a/src/VBox/HostDrivers/Support/SUPSvc.cpp b/src/VBox/HostDrivers/Support/SUPSvc.cpp
index de087be5..c3921bcf 100644
--- a/src/VBox/HostDrivers/Support/SUPSvc.cpp
+++ b/src/VBox/HostDrivers/Support/SUPSvc.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp b/src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp
index f58a03ad..fe67b7fc 100644
--- a/src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp
+++ b/src/VBox/HostDrivers/Support/SUPSvcGlobal.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPSvcGrant.cpp b/src/VBox/HostDrivers/Support/SUPSvcGrant.cpp
index 50a9cdef..e4ec5c03 100644
--- a/src/VBox/HostDrivers/Support/SUPSvcGrant.cpp
+++ b/src/VBox/HostDrivers/Support/SUPSvcGrant.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/SUPSvcInternal.h b/src/VBox/HostDrivers/Support/SUPSvcInternal.h
index afdc78f4..b510c8ff 100644
--- a/src/VBox/HostDrivers/Support/SUPSvcInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPSvcInternal.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/darwin/Info.plist b/src/VBox/HostDrivers/Support/darwin/Info.plist
index d6619884..e010a700 100644
--- a/src/VBox/HostDrivers/Support/darwin/Info.plist
+++ b/src/VBox/HostDrivers/Support/darwin/Info.plist
@@ -1,4 +1,4 @@
-
+<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
diff --git a/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp b/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
index d91f34de..33803bca 100644
--- a/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
+++ b/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -42,6 +42,7 @@
#include "../SUPDrvInternal.h"
#include <VBox/version.h>
#include <iprt/asm.h>
+#include <iprt/asm-amd64-x86.h>
#include <iprt/initterm.h>
#include <iprt/assert.h>
#include <iprt/spinlock.h>
@@ -49,6 +50,7 @@
#include <iprt/process.h>
#include <iprt/alloc.h>
#include <iprt/power.h>
+#include <iprt/dbg.h>
#include <VBox/err.h>
#include <VBox/log.h>
@@ -64,6 +66,9 @@
#include <IOKit/IOUserClient.h>
#include <IOKit/pwr_mgt/RootDomain.h>
#include <IOKit/IODeviceTreeSupport.h>
+#include <IOKit/usb/IOUSBHIDDriver.h>
+#include <IOKit/bluetooth/IOBluetoothHIDDriver.h>
+#include <IOKit/bluetooth/IOBluetoothHIDDriverTypes.h>
#ifdef VBOX_WITH_HOST_VMX
# include <libkern/version.h>
@@ -77,8 +82,10 @@ RT_C_DECLS_END
* Defined Constants And Macros *
*******************************************************************************/
-/** The module name. */
-#define DEVICE_NAME "vboxdrv"
+/** The system device node name. */
+#define DEVICE_NAME_SYS "vboxdrv"
+/** The user device node name. */
+#define DEVICE_NAME_USR "vboxdrvu"
@@ -99,6 +106,8 @@ static int VBoxDrvDarwinErr2DarwinErr(int rc);
static IOReturn VBoxDrvDarwinSleepHandler(void *pvTarget, void *pvRefCon, UInt32 uMessageType, IOService *pProvider, void *pvMessageArgument, vm_size_t argSize);
RT_C_DECLS_END
+static void vboxdrvDarwinResolveSymbols(void);
+
/*******************************************************************************
* Structures and Typedefs *
@@ -198,8 +207,10 @@ static struct cdevsw g_DevCW =
/** Major device number. */
static int g_iMajorDeviceNo = -1;
-/** Registered devfs device handle. */
-static void *g_hDevFsDevice = NULL;
+/** Registered devfs device handle for the system device. */
+static void *g_hDevFsDeviceSys = NULL;
+/** Registered devfs device handle for the user device. */
+static void *g_hDevFsDeviceUsr = NULL;
/** Spinlock protecting g_apSessionHashTab. */
static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
@@ -210,8 +221,14 @@ static PSUPDRVSESSION g_apSessionHashTab[19];
/** The number of open sessions. */
static int32_t volatile g_cSessions = 0;
/** The notifier handle for the sleep callback handler. */
-static IONotifier *g_pSleepNotifier = NULL;
+static IONotifier *g_pSleepNotifier = NULL;
+/** Pointer to vmx_suspend(). */
+static PFNRT g_pfnVmxSuspend = NULL;
+/** Pointer to vmx_resume(). */
+static PFNRT g_pfnVmxResume = NULL;
+/** Pointer to vmx_use_count. */
+static int volatile *g_pVmxUseCount = NULL;
/**
@@ -250,26 +267,38 @@ static kern_return_t VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pv
if (g_iMajorDeviceNo >= 0)
{
#ifdef VBOX_WITH_HARDENING
- g_hDevFsDevice = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
- UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME);
+ g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
+ UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
#else
- g_hDevFsDevice = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
- UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME);
+ g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
+ UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
#endif
- if (g_hDevFsDevice)
+ if (g_hDevFsDeviceSys)
{
- 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"));
-
- return KMOD_RETURN_SUCCESS;
+ 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));
- LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME));
cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
g_iMajorDeviceNo = -1;
}
@@ -295,6 +324,39 @@ static kern_return_t VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pv
/**
+ * Resolves kernel symbols we want (but may do without).
+ */
+static void vboxdrvDarwinResolveSymbols(void)
+{
+ RTDBGKRNLINFO hKrnlInfo;
+ int rc = RTR0DbgKrnlInfoOpen(&hKrnlInfo, 0);
+ if (RT_SUCCESS(rc))
+ {
+ /* The VMX stuff. */
+ int rc1 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_resume", (void **)&g_pfnVmxResume);
+ int rc2 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_suspend", (void **)&g_pfnVmxSuspend);
+ int rc3 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_use_count", (void **)&g_pVmxUseCount);
+ if (RT_SUCCESS(rc1) && RT_SUCCESS(rc2) && RT_SUCCESS(rc3))
+ {
+ LogRel(("VBoxDrv: vmx_resume=%p vmx_suspend=%p vmx_use_count=%p (%d) cr4=%#x\n",
+ g_pfnVmxResume, g_pfnVmxSuspend, g_pVmxUseCount, *g_pVmxUseCount, ASMGetCR4() ));
+ }
+ else
+ {
+ LogRel(("VBoxDrv: failed to resolve vmx stuff: vmx_resume=%Rrc vmx_suspend=%Rrc vmx_use_count=%Rrc", rc1, rc2, rc3));
+ g_pfnVmxResume = NULL;
+ g_pfnVmxSuspend = NULL;
+ g_pVmxUseCount = NULL;
+ }
+
+ RTR0DbgKrnlInfoRelease(hKrnlInfo);
+ }
+ else
+ LogRel(("VBoxDrv: Failed to open kernel symbols, rc=%Rrc\n", rc));
+}
+
+
+/**
* Stop the kernel module.
*/
static kern_return_t VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData)
@@ -314,8 +376,11 @@ static kern_return_t VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvD
g_pSleepNotifier = NULL;
}
- devfs_remove(g_hDevFsDevice);
- g_hDevFsDevice = NULL;
+ devfs_remove(g_hDevFsDeviceUsr);
+ g_hDevFsDeviceUsr = NULL;
+
+ devfs_remove(g_hDevFsDeviceSys);
+ g_hDevFsDeviceSys = NULL;
rc = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
Assert(rc == g_iMajorDeviceNo);
@@ -340,8 +405,10 @@ static kern_return_t VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvD
/**
* Device open. Called on open /dev/vboxdrv
*
- * @param pInode Pointer to inode info structure.
- * @param pFilp Associated file pointer.
+ * @param Dev The device number.
+ * @param fFlags ???.
+ * @param fDevType ???.
+ * @param pProcess The process issuing this request.
*/
static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
{
@@ -353,10 +420,17 @@ static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *p
#endif
/*
+ * Only two minor devices numbers are allowed.
+ */
+ if (minor(Dev) != 0 && minor(Dev) != 1)
+ return EACCES;
+
+ /*
* Find the session created by org_virtualbox_SupDrvClient, fail
* if no such session, and mark it as opened. We set the uid & gid
* here too, since that is more straight forward at this point.
*/
+ const bool fUnrestricted = minor(Dev) == 0;
int rc = VINF_SUCCESS;
PSUPDRVSESSION pSession = NULL;
kauth_cred_t pCred = kauth_cred_proc_ref(pProcess);
@@ -374,16 +448,14 @@ static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *p
RTSpinlockAcquire(g_Spinlock);
pSession = g_apSessionHashTab[iHash];
- if (pSession && pSession->Process != Process)
- {
- do pSession = pSession->pNextHash;
- while (pSession && pSession->Process != Process);
- }
+ while (pSession && pSession->Process != Process)
+ pSession = pSession->pNextHash;
if (pSession)
{
if (!pSession->fOpened)
{
pSession->fOpened = true;
+ pSession->fUnrestricted = fUnrestricted;
pSession->Uid = Uid;
pSession->Gid = Gid;
}
@@ -442,6 +514,7 @@ static int VBoxDrvDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *
*/
static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
{
+ const bool fUnrestricted = minor(Dev) == 0;
const RTPROCESS Process = proc_pid(pProcess);
const unsigned iHash = SESSION_HASH(Process);
PSUPDRVSESSION pSession;
@@ -451,11 +524,11 @@ static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags,
*/
RTSpinlockAcquire(g_Spinlock);
pSession = g_apSessionHashTab[iHash];
- if (pSession && pSession->Process != Process)
- {
- do pSession = pSession->pNextHash;
- while (pSession && pSession->Process != Process);
- }
+ while (pSession && pSession->Process != Process && pSession->fUnrestricted == fUnrestricted && pSession->fOpened)
+ pSession = pSession->pNextHash;
+
+ if (RT_LIKELY(pSession))
+ supdrvSessionRetain(pSession);
RTSpinlockReleaseNoInts(g_Spinlock);
if (!pSession)
{
@@ -468,11 +541,17 @@ static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags,
* Deal with the two high-speed IOCtl that takes it's arguments from
* the session and iCmd, and only returns a VBox status code.
*/
- if ( iCmd == SUP_IOCTL_FAST_DO_RAW_RUN
- || iCmd == SUP_IOCTL_FAST_DO_HWACC_RUN
- || iCmd == SUP_IOCTL_FAST_DO_NOP)
- return supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
- return VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
+ int rc;
+ if ( ( iCmd == SUP_IOCTL_FAST_DO_RAW_RUN
+ || iCmd == SUP_IOCTL_FAST_DO_HM_RUN
+ || iCmd == SUP_IOCTL_FAST_DO_NOP)
+ && fUnrestricted)
+ rc = supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
+ else
+ rc = VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
+
+ supdrvSessionRelease(pSession);
+ return rc;
}
@@ -633,7 +712,7 @@ static int VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t
* @param iReq The request code.
* @param pReq The request.
*/
-int VBOXCALL SUPDrvDarwinIDC(uint32_t uReq, PSUPDRVIDCREQHDR pReq)
+DECLEXPORT(int) VBOXCALL SUPDrvDarwinIDC(uint32_t uReq, PSUPDRVIDCREQHDR pReq)
{
PSUPDRVSESSION pSession;
@@ -710,16 +789,16 @@ IOReturn VBoxDrvDarwinSleepHandler(void * /* pvTarget */, void *pvRefCon, UInt32
/**
- * Enables or disables VT-x using kernel functions.
- *
- * @returns VBox status code. VERR_NOT_SUPPORTED has a special meaning.
- * @param fEnable Whether to enable or disable.
+ * @copydoc SUPR0EnableVTx
*/
int VBOXCALL supdrvOSEnableVTx(bool fEnable)
{
#ifdef VBOX_WITH_HOST_VMX
int rc;
- if (version_major >= 10 /* 10 = 10.6.x = Snow Leopard */)
+ if ( version_major >= 10 /* 10 = 10.6.x = Snow Leopard */
+ && g_pfnVmxSuspend
+ && g_pfnVmxResume
+ && g_pVmxUseCount)
{
if (fEnable)
{
@@ -735,11 +814,13 @@ int VBOXCALL supdrvOSEnableVTx(bool fEnable)
LogRel(("host_vmxon returned %d\n", rc));
rc = VERR_UNRESOLVED_ERROR;
}
+ LogRel(("VBoxDrv: host_vmxon -> vmx_use_count=%d rc=%Rrc\n", *g_pVmxUseCount, rc));
}
else
{
host_vmxoff();
rc = VINF_SUCCESS;
+ LogRel(("VBoxDrv: host_vmxoff -> vmx_use_count=%d\n", *g_pVmxUseCount));
}
}
else
@@ -755,6 +836,54 @@ int VBOXCALL supdrvOSEnableVTx(bool fEnable)
}
+/**
+ * @copydoc SUPR0SuspendVTxOnCpu
+ */
+bool VBOXCALL supdrvOSSuspendVTxOnCpu(void)
+{
+#ifdef VBOX_WITH_HOST_VMX
+ /*
+ * Consult the VMX usage counter, don't try suspend if not enabled.
+ *
+ * Note! The host_vmxon/off code is still race prone since, but this is
+ * currently the best we can do without always enable VMX when
+ * loading the driver.
+ */
+ if ( g_pVmxUseCount
+ && *g_pVmxUseCount > 0)
+ {
+ g_pfnVmxSuspend();
+ return true;
+ }
+ return false;
+#else
+ return false;
+#endif
+}
+
+
+/**
+ * @copydoc SUPR0ResumeVTxOnCpu
+ */
+void VBOXCALL supdrvOSResumeVTxOnCpu(bool fSuspended)
+{
+#ifdef VBOX_WITH_HOST_VMX
+ /*
+ * Don't consult the counter here, the state knows better.
+ * We're executing with interrupts disabled and anyone racing us with
+ * disabling VT-x will be waiting in the rendezvous code.
+ */
+ if ( fSuspended
+ && g_pfnVmxResume)
+ g_pfnVmxResume();
+ else
+ Assert(!fSuspended);
+#else
+ Assert(!fSuspended);
+#endif
+}
+
+
bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
{
NOREF(pDevExt);
@@ -817,6 +946,72 @@ void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
/**
+ * Resume Bluetooth keyboard.
+ * If there is no Bluetooth keyboard device connected to the system we just ignore this.
+ */
+static void supdrvDarwinResumeBluetoothKbd(void)
+{
+ OSDictionary *pDictionary = IOService::serviceMatching("AppleBluetoothHIDKeyboard");
+ if (pDictionary)
+ {
+ OSIterator *pIter;
+ IOBluetoothHIDDriver *pDriver;
+
+ pIter = IOService::getMatchingServices(pDictionary);
+ if (pIter)
+ {
+ while ((pDriver = (IOBluetoothHIDDriver *)pIter->getNextObject()))
+ if (pDriver->isKeyboard())
+ (void)pDriver->hidControl(IOBTHID_CONTROL_EXIT_SUSPEND);
+
+ pIter->release();
+ }
+ pDictionary->release();
+ }
+}
+
+/**
+ * Resume built-in keyboard on MacBook Air and Pro hosts.
+ * If there is no built-in keyboard device attached to the system we just ignore this.
+ */
+static void supdrvDarwinResumeBuiltinKbd(void)
+{
+ /*
+ * AppleUSBTCKeyboard KEXT is responsible for built-in keyboard management.
+ * We resume keyboard by accessing to its IOService. */
+ OSDictionary *pDictionary = IOService::serviceMatching("AppleUSBTCKeyboard");
+ if (pDictionary)
+ {
+ OSIterator *pIter;
+ IOUSBHIDDriver *pDriver;
+
+ pIter = IOService::getMatchingServices(pDictionary);
+ if (pIter)
+ {
+ while ((pDriver = (IOUSBHIDDriver *)pIter->getNextObject()))
+ if (pDriver->IsPortSuspended())
+ pDriver->SuspendPort(false, 0);
+
+ pIter->release();
+ }
+ pDictionary->release();
+ }
+}
+
+
+/**
+ * Resume suspended keyboard devices (if any).
+ */
+int VBOXCALL supdrvDarwinResumeSuspendedKbds(void)
+{
+ supdrvDarwinResumeBuiltinKbd();
+ supdrvDarwinResumeBluetoothKbd();
+
+ return 0;
+}
+
+
+/**
* Converts an IPRT error code to a darwin error code.
*
* @returns corresponding darwin error code.
@@ -998,15 +1193,15 @@ bool org_virtualbox_SupDrvClient::start(IOService *pProvider)
/*
* Create a new session.
*/
- int rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &m_pSession);
+ int rc = supdrvCreateSession(&g_DevExt, true /* fUser */, false /*fUnrestricted*/, &m_pSession);
if (RT_SUCCESS(rc))
{
m_pSession->fOpened = false;
- /* The Uid and Gid fields are set on open. */
+ /* The Uid, Gid and fUnrestricted fields are set on open. */
/*
* Insert it into the hash table, checking that there isn't
- * already one for this process first.
+ * already one for this process first. (One session per proc!)
*/
unsigned iHash = SESSION_HASH(m_pSession->Process);
RTSpinlockAcquire(g_Spinlock);
@@ -1036,7 +1231,7 @@ bool org_virtualbox_SupDrvClient::start(IOService *pProvider)
}
LogFlow(("org_virtualbox_SupDrvClient::start: already got a session for this process (%p)\n", pCur));
- supdrvCloseSession(&g_DevExt, m_pSession);
+ supdrvSessionRelease(m_pSession);
}
m_pSession = NULL;
@@ -1051,13 +1246,14 @@ bool org_virtualbox_SupDrvClient::start(IOService *pProvider)
/**
* Common worker for clientClose and VBoxDrvDarwinClose.
- *
- * It will
*/
/* static */ void org_virtualbox_SupDrvClient::sessionClose(RTPROCESS Process)
{
/*
- * Look for the session.
+ * Find the session and remove it from the hash table.
+ *
+ * Note! Only one session per process. (Both start() and
+ * VBoxDrvDarwinOpen makes sure this is so.)
*/
const unsigned iHash = SESSION_HASH(Process);
RTSpinlockAcquire(g_Spinlock);
@@ -1111,7 +1307,7 @@ bool org_virtualbox_SupDrvClient::start(IOService *pProvider)
/*
* Close the session.
*/
- supdrvCloseSession(&g_DevExt, pSession);
+ supdrvSessionRelease(pSession);
}
diff --git a/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp b/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp
index 5d5b03d3..69567b8a 100644
--- a/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp
+++ b/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -61,8 +61,10 @@
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
-/** BSD Device name. */
-#define DEVICE_NAME "/dev/vboxdrv"
+/** System device name. */
+#define DEVICE_NAME_SYS "/dev/vboxdrv"
+/** User device name. */
+#define DEVICE_NAME_USR "/dev/vboxdrvu"
/** The IOClass key of the service (see SUPDrv-darwin.cpp / Info.plist). */
#define IOCLASS_NAME "org_virtualbox_SupDrv"
@@ -73,14 +75,14 @@
*
* @returns VBox status code.
*/
-static int suplibDarwinOpenDevice(PSUPLIBDATA pThis)
+static int suplibDarwinOpenDevice(PSUPLIBDATA pThis, bool fUnrestricted)
{
/*
* Open the BSD device.
* This will connect to the session created when the SupDrvClient was
* started, so it has to be done after opening the service (IOC v9.1+).
*/
- int hDevice = open(DEVICE_NAME, O_RDWR, 0);
+ int hDevice = open(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, O_RDWR, 0);
if (hDevice < 0)
{
int rc;
@@ -92,7 +94,7 @@ static int suplibDarwinOpenDevice(PSUPLIBDATA pThis)
case ENOENT: rc = VERR_VM_DRIVER_NOT_INSTALLED; break;
default: rc = VERR_VM_DRIVER_OPEN_ERROR; break;
}
- LogRel(("SUP: Failed to open \"%s\", errno=%d, rc=%Rrc\n", DEVICE_NAME, errno, rc));
+ LogRel(("SUP: Failed to open \"%s\", errno=%d, rc=%Rrc\n", fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, errno, rc));
return rc;
}
@@ -112,7 +114,8 @@ static int suplibDarwinOpenDevice(PSUPLIBDATA pThis)
return rc;
}
- pThis->hDevice = hDevice;
+ pThis->hDevice = hDevice;
+ pThis->fUnrestricted = fUnrestricted;
return VINF_SUCCESS;
}
@@ -182,7 +185,7 @@ static int suplibDarwinOpenService(PSUPLIBDATA pThis)
}
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
{
/*
* Nothing to do if pre-inited.
@@ -197,7 +200,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
int rc = suplibDarwinOpenService(pThis);
if (RT_SUCCESS(rc))
{
- rc = suplibDarwinOpenDevice(pThis);
+ rc = suplibDarwinOpenDevice(pThis, fUnrestricted);
if (RT_FAILURE(rc))
{
kern_return_t kr = IOServiceClose((io_connect_t)pThis->uConnection);
diff --git a/src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c b/src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c
index 128a6907..14e6a8c2 100644
--- a/src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c
+++ b/src/VBox/HostDrivers/Support/darwin/SUPR0IdcClient-darwin.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c b/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
index d5e38de2..f0166b98 100644
--- a/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
+++ b/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
@@ -70,7 +70,8 @@ static int VBoxDrvFreeBSDModuleEvent(struct module *pMod, int enmEventType, void
static int VBoxDrvFreeBSDLoad(void);
static int VBoxDrvFreeBSDUnload(void);
-static d_open_t VBoxDrvFreeBSDOpen;
+static d_open_t VBoxDrvFreeBSDOpenUsr;
+static d_open_t VBoxDrvFreeBSDOpenSys;
static void VBoxDrvFreeBSDDtr(void *pData);
static d_ioctl_t VBoxDrvFreeBSDIOCtl;
static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd);
@@ -96,16 +97,29 @@ MODULE_VERSION(vboxdrv, 1);
/**
* The /dev/vboxdrv character device entry points.
*/
-static struct cdevsw g_VBoxDrvFreeBSDChrDevSW =
+static struct cdevsw g_VBoxDrvFreeBSDChrDevSwSys =
{
.d_version = D_VERSION,
- .d_open = VBoxDrvFreeBSDOpen,
+ .d_open = VBoxDrvFreeBSDOpenSys,
.d_ioctl = VBoxDrvFreeBSDIOCtl,
.d_name = "vboxdrv"
};
-
/** The /dev/vboxdrv character device. */
-static struct cdev *g_pVBoxDrvFreeBSDChrDev;
+static struct cdev *g_pVBoxDrvFreeBSDChrDevSys;
+
+/**
+ * The /dev/vboxdrvu character device entry points.
+ */
+static struct cdevsw g_VBoxDrvFreeBSDChrDevSwUsr =
+{
+ .d_version = D_VERSION,
+ .d_open = VBoxDrvFreeBSDOpenUsr,
+ .d_ioctl = VBoxDrvFreeBSDIOCtl,
+ .d_name = "vboxdrvu"
+};
+/** The /dev/vboxdrvu character device. */
+static struct cdev *g_pVBoxDrvFreeBSDChrDevUsr;
+
/** Reference counter. */
static volatile uint32_t g_cUsers;
@@ -167,13 +181,14 @@ static int VBoxDrvFreeBSDLoad(void)
if (RT_SUCCESS(rc))
{
/*
- * Configure character device. Add symbolic link for compatibility.
+ * Configure character devices. Add symbolic links for compatibility.
*/
- g_pVBoxDrvFreeBSDChrDev = make_dev(&g_VBoxDrvFreeBSDChrDevSW, 0, UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv");
+ g_pVBoxDrvFreeBSDChrDevSys = make_dev(&g_VBoxDrvFreeBSDChrDevSwSys, 0, UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv");
+ g_pVBoxDrvFreeBSDChrDevUsr = make_dev(&g_VBoxDrvFreeBSDChrDevSwUsr, 1, UID_ROOT, GID_WHEEL, 0666, "vboxdrvu");
return VINF_SUCCESS;
}
- else
- printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc);
+
+ printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc);
RTR0Term();
}
else
@@ -191,7 +206,8 @@ static int VBoxDrvFreeBSDUnload(void)
/*
* Reserve what we did in VBoxDrvFreeBSDInit.
*/
- destroy_dev(g_pVBoxDrvFreeBSDChrDev);
+ destroy_dev(g_pVBoxDrvFreeBSDChrDevUsr);
+ destroy_dev(g_pVBoxDrvFreeBSDChrDevSys);
supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt);
@@ -206,13 +222,12 @@ static int VBoxDrvFreeBSDUnload(void)
*
* @returns 0 on success, errno on failure.
* EBUSY if the device is used by someone else.
- * @param pDev The device node.
- * @param fOpen The open flags.
- * @param pTd The thread.
- * @param pFd The file descriptor. FreeBSD 7.0 and later.
- * @param iFd The file descriptor index(?). Pre FreeBSD 7.0.
+ * @param pDev The device node.
+ * @param fOpen The open flags.
+ * @param pTd The thread.
+ * @param iDevType ???
*/
-static int VBoxDrvFreeBSDOpen(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd)
+static int vboxdrvFreeBSDOpenCommon(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd, bool fUnrestricted)
{
PSUPDRVSESSION pSession;
int rc;
@@ -220,7 +235,7 @@ static int VBoxDrvFreeBSDOpen(struct cdev *pDev, int fOpen, int iDevtype, struct
/*
* Let's be a bit picky about the flags...
*/
- if (fOpen != (FREAD|FWRITE /*=O_RDWR*/))
+ if (fOpen != (FREAD | FWRITE /*=O_RDWR*/))
{
Log(("VBoxDrvFreeBSDOpen: fOpen=%#x expected %#x\n", fOpen, O_RDWR));
return EINVAL;
@@ -229,7 +244,7 @@ static int VBoxDrvFreeBSDOpen(struct cdev *pDev, int fOpen, int iDevtype, struct
/*
* Create a new session.
*/
- rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, &pSession);
+ rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, fUnrestricted, &pSession);
if (RT_SUCCESS(rc))
{
/** @todo get (r)uid and (r)gid.
@@ -245,6 +260,20 @@ static int VBoxDrvFreeBSDOpen(struct cdev *pDev, int fOpen, int iDevtype, struct
}
+/** For vboxdrv. */
+static int VBoxDrvFreeBSDOpenSys(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd)
+{
+ return vboxdrvFreeBSDOpenCommon(pDev, fOpen, iDevtype, pTd, true);
+}
+
+
+/** For vboxdrvu. */
+static int VBoxDrvFreeBSDOpenUsr(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd)
+{
+ return vboxdrvFreeBSDOpenCommon(pDev, fOpen, iDevtype, pTd, false);
+}
+
+
/**
* Close a file device previously opened by VBoxDrvFreeBSDOpen
*
@@ -262,7 +291,7 @@ static void VBoxDrvFreeBSDDtr(void *pData)
/*
* Close the session.
*/
- supdrvCloseSession(&g_VBoxDrvFreeBSDDevExt, pSession);
+ supdrvSessionRelease(pSession);
ASMAtomicDecU32(&g_cUsers);
}
@@ -285,9 +314,10 @@ static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_long ulCmd, caddr_t pvData,
/*
* Deal with the fast ioctl path first.
*/
- if ( ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN
- || ulCmd == SUP_IOCTL_FAST_DO_HWACC_RUN
- || ulCmd == SUP_IOCTL_FAST_DO_NOP)
+ if ( ( ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN
+ || ulCmd == SUP_IOCTL_FAST_DO_HM_RUN
+ || ulCmd == SUP_IOCTL_FAST_DO_NOP)
+ && pSession->fUnrestricted == true)
return supdrvIOCtlFast(ulCmd, *(uint32_t *)pvData, &g_VBoxDrvFreeBSDDevExt, pSession);
return VBoxDrvFreeBSDIOCtlSlow(pSession, ulCmd, pvData, pTd);
diff --git a/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp b/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp
index 6c16f5e9..c5ca90da 100644
--- a/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp
+++ b/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -60,12 +60,14 @@
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
-/** FreeBSD base device name. */
-#define DEVICE_NAME "/dev/vboxdrv"
+/** System device name. */
+#define DEVICE_NAME_SYS "/dev/vboxdrv"
+/** User device name. */
+#define DEVICE_NAME_USR "/dev/vboxdrvu"
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
{
/*
* Nothing to do if pre-inited.
@@ -76,7 +78,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* Try open the BSD device.
*/
- int hDevice = open(DEVICE_NAME, O_RDWR, 0);
+ int hDevice = open(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, O_RDWR, 0);
if (hDevice < 0)
{
int rc;
@@ -88,7 +90,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
case ENOENT: rc = VERR_VM_DRIVER_NOT_INSTALLED; break;
default: rc = VERR_VM_DRIVER_OPEN_ERROR; break;
}
- LogRel(("Failed to open \"%s\", errno=%d, rc=%Rrc\n", DEVICE_NAME, errno, rc));
+ LogRel(("Failed to open \"%s\", errno=%d, rc=%Rrc\n", fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, errno, rc));
return rc;
}
@@ -111,7 +113,8 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* We're done.
*/
- pThis->hDevice = hDevice;
+ pThis->hDevice = hDevice;
+ pThis->fUnrestricted = fUnrestricted;
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c b/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c
index b0e39038..ed080886 100644
--- a/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c
+++ b/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv b/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
index d597425c..b02e35ca 100755
--- a/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
+++ b/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
@@ -81,8 +81,8 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/include/VBox/version.h=>include/VBox/version.h \
${PATH_ROOT}/include/VBox/SUPDrvMangling.h=>include/VBox/SUPDrvMangling.h \
${PATH_ROOT}/include/VBox/VBoxTpG.h=>include/VBox/VBoxTpG.h \
- ${PATH_ROOT}/include/VBox/vmm/hwacc_vmx.h=>include/VBox/vmm/hwacc_vmx.h \
- ${PATH_ROOT}/include/VBox/vmm/hwacc_svm.h=>include/VBox/vmm/hwacc_svm.h \
+ ${PATH_ROOT}/include/VBox/vmm/hm_vmx.h=>include/VBox/vmm/hm_vmx.h \
+ ${PATH_ROOT}/include/VBox/vmm/hm_svm.h=>include/VBox/vmm/hm_svm.h \
${PATH_ROOT}/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c=>freebsd/SUPDrv-freebsd.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrv.c=>SUPDrv.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvSem.c=>SUPDrvSem.c \
@@ -193,6 +193,7 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h=>r0drv/freebsd/sleepqueue-r0drv-freebsd.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c=>r0drv/generic/semspinmutex-r0drv-generic.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp=>r0drv/generic/mpnotification-r0drv-generic.c \
+ ${PATH_ROOT}/src/VBox/Runtime/r0drv/generic/threadctxhooks-r0drv-generic.cpp=>r0drv/generic/threadctxhooks-r0drv-generic.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp=>r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/memobj-r0drv.cpp=>r0drv/memobj-r0drv.c \
${PATH_ROOT}/src/VBox/Runtime/VBox/log-vbox.cpp=>VBox/log-vbox.c \
diff --git a/src/VBox/HostDrivers/Support/linux/Makefile b/src/VBox/HostDrivers/Support/linux/Makefile
index 8ca3529e..af9f644d 100644
--- a/src/VBox/HostDrivers/Support/linux/Makefile
+++ b/src/VBox/HostDrivers/Support/linux/Makefile
@@ -94,6 +94,7 @@ OBJS = \
r0drv/linux/spinlock-r0drv-linux.o \
r0drv/linux/thread-r0drv-linux.o \
r0drv/linux/thread2-r0drv-linux.o \
+ r0drv/linux/threadctxhooks-r0drv-linux.o \
r0drv/linux/time-r0drv-linux.o \
r0drv/linux/timer-r0drv-linux.o \
r0drv/generic/semspinmutex-r0drv-generic.o \
@@ -139,6 +140,7 @@ OBJS = \
generic/RTLogWriteStdOut-stub-generic.o \
generic/RTLogWriteUser-generic.o \
generic/RTMpGetArraySize-generic.o \
+ generic/RTMpGetCoreCount-generic.o \
generic/RTSemEventWait-2-ex-generic.o \
generic/RTSemEventWaitNoResume-2-ex-generic.o \
generic/RTSemEventMultiWait-2-ex-generic.o \
@@ -247,7 +249,8 @@ else
MANGLING := $(KBUILD_EXTMOD)/include/VBox/SUPDrvMangling.h
endif
KFLAGS := -D__KERNEL__ -DMODULE -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \
- -DIN_SUP_R0 -DVBOX -DRT_WITH_VBOX -DVBOX_WITH_HARDENING
+ -DIN_SUP_R0 -DVBOX -DRT_WITH_VBOX -DVBOX_WITH_HARDENING \
+ -Wno-declaration-after-statement
ifdef VBOX_REDHAT_KABI
KFLAGS += -DVBOX_REDHAT_KABI
endif
diff --git a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
index 80066ce8..6000e9d4 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
+++ b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
@@ -1,10 +1,10 @@
-/* $Rev: 77635 $ */
+/* $Rev: 87729 $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Linux specifics.
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -95,14 +95,15 @@
*******************************************************************************/
static int VBoxDrvLinuxInit(void);
static void VBoxDrvLinuxUnload(void);
-static int VBoxDrvLinuxCreate(struct inode *pInode, struct file *pFilp);
+static int VBoxDrvLinuxCreateSys(struct inode *pInode, struct file *pFilp);
+static int VBoxDrvLinuxCreateUsr(struct inode *pInode, struct file *pFilp);
static int VBoxDrvLinuxClose(struct inode *pInode, struct file *pFilp);
#ifdef HAVE_UNLOCKED_IOCTL
static long VBoxDrvLinuxIOCtl(struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
#else
static int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
#endif
-static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
+static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg, PSUPDRVSESSION pSession);
static int VBoxDrvLinuxErr2LinuxErr(int);
#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
static int VBoxDrvProbe(struct platform_device *pDev);
@@ -126,20 +127,26 @@ static void VBoxDevRelease(struct device *pDev);
static SUPDRVDEVEXT g_DevExt;
#ifndef CONFIG_VBOXDRV_AS_MISC
-/** Module major number */
-#define DEVICE_MAJOR 234
-/** Saved major device number */
-static int g_iModuleMajor;
+/** Module major number for vboxdrv. */
+#define DEVICE_MAJOR_SYS 234
+/** Saved major device number for vboxdrv. */
+static int g_iModuleMajorSys;
+/** Module major number for vboxdrvu. */
+#define DEVICE_MAJOR_USR 235
+/** Saved major device number for vboxdrvu. */
+static int g_iModuleMajorUsr;
#endif /* !CONFIG_VBOXDRV_AS_MISC */
/** Module parameter.
* Not prefixed because the name is used by macros and the end of this file. */
static int force_async_tsc = 0;
-/** The module name. */
-#define DEVICE_NAME "vboxdrv"
+/** The system device name. */
+#define DEVICE_NAME_SYS "vboxdrv"
+/** The user device name. */
+#define DEVICE_NAME_USR "vboxdrvu"
-#if defined(RT_ARCH_AMD64) && !defined(CONFIG_DEBUG_SET_MODULE_RONX)
+#if defined(RT_ARCH_AMD64) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
/**
* Memory for the executable memory heap (in IPRT).
*/
@@ -155,10 +162,23 @@ __asm__(".section execmemory, \"awx\", @progbits\n\t"
#endif
/** The file_operations structure. */
-static struct file_operations gFileOpsVBoxDrv =
+static struct file_operations gFileOpsVBoxDrvSys =
+{
+ owner: THIS_MODULE,
+ open: VBoxDrvLinuxCreateSys,
+ release: VBoxDrvLinuxClose,
+#ifdef HAVE_UNLOCKED_IOCTL
+ unlocked_ioctl: VBoxDrvLinuxIOCtl,
+#else
+ ioctl: VBoxDrvLinuxIOCtl,
+#endif
+};
+
+/** The file_operations structure. */
+static struct file_operations gFileOpsVBoxDrvUsr =
{
owner: THIS_MODULE,
- open: VBoxDrvLinuxCreate,
+ open: VBoxDrvLinuxCreateUsr,
release: VBoxDrvLinuxClose,
#ifdef HAVE_UNLOCKED_IOCTL
unlocked_ioctl: VBoxDrvLinuxIOCtl,
@@ -168,14 +188,24 @@ static struct file_operations gFileOpsVBoxDrv =
};
#ifdef CONFIG_VBOXDRV_AS_MISC
-/** The miscdevice structure. */
-static struct miscdevice gMiscDevice =
+/** The miscdevice structure for vboxdrv. */
+static struct miscdevice gMiscDeviceSys =
{
minor: MISC_DYNAMIC_MINOR,
- name: DEVICE_NAME,
- fops: &gFileOpsVBoxDrv,
+ name: DEVICE_NAME_SYS,
+ fops: &gFileOpsVBoxDrvSys,
# if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
- devfs_name: DEVICE_NAME,
+ devfs_name: DEVICE_NAME_SYS,
+# endif
+};
+/** The miscdevice structure for vboxdrvu. */
+static struct miscdevice gMiscDeviceUsr =
+{
+ minor: MISC_DYNAMIC_MINOR,
+ name: DEVICE_NAME_USR,
+ fops: &gFileOpsVBoxDrvUsr,
+# if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
+ devfs_name: DEVICE_NAME_USR,
# endif
};
#endif
@@ -223,7 +253,11 @@ static struct platform_device gPlatformDevice =
DECLINLINE(RTUID) vboxdrvLinuxUid(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ return from_kuid(current_user_ns(), current->cred->uid);
+# else
return current->cred->uid;
+# endif
#else
return current->uid;
#endif
@@ -232,7 +266,11 @@ DECLINLINE(RTUID) vboxdrvLinuxUid(void)
DECLINLINE(RTGID) vboxdrvLinuxGid(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ return from_kgid(current_user_ns(), current->cred->gid);
+# else
return current->cred->gid;
+# endif
#else
return current->gid;
#endif
@@ -241,7 +279,11 @@ DECLINLINE(RTGID) vboxdrvLinuxGid(void)
DECLINLINE(RTUID) vboxdrvLinuxEuid(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ return from_kuid(current_user_ns(), current->cred->euid);
+# else
return current->cred->euid;
+# endif
#else
return current->euid;
#endif
@@ -259,40 +301,60 @@ static int __init VBoxDrvLinuxInit(void)
/*
* Check for synchronous/asynchronous TSC mode.
*/
- printk(KERN_DEBUG DEVICE_NAME ": Found %u processor cores.\n", (unsigned)RTMpGetOnlineCount());
+ printk(KERN_DEBUG "vboxdrv: Found %u processor cores.\n", (unsigned)RTMpGetOnlineCount());
#ifdef CONFIG_VBOXDRV_AS_MISC
- rc = misc_register(&gMiscDevice);
+ rc = misc_register(&gMiscDeviceSys);
+ if (rc)
+ {
+ printk(KERN_ERR "vboxdrv: Can't register system misc device! rc=%d\n", rc);
+ return rc;
+ }
+ rc = misc_register(&gMiscDeviceUsr);
if (rc)
{
- printk(KERN_ERR DEVICE_NAME ": Can't register misc device! rc=%d\n", rc);
+ printk(KERN_ERR "vboxdrv: Can't register user misc device! rc=%d\n", rc);
+ misc_deregister(&gMiscDeviceSys);
return rc;
}
#else /* !CONFIG_VBOXDRV_AS_MISC */
/*
- * Register character device.
+ * Register character devices and save the returned major numbers.
*/
- g_iModuleMajor = DEVICE_MAJOR;
- rc = register_chrdev((dev_t)g_iModuleMajor, DEVICE_NAME, &gFileOpsVBoxDrv);
+ /* /dev/vboxdrv */
+ g_iModuleMajorSys = DEVICE_MAJOR_SYS;
+ rc = register_chrdev((dev_t)g_iModuleMajorSys, DEVICE_NAME_SYS, &gFileOpsVBoxDrvSys);
if (rc < 0)
{
- Log(("register_chrdev() failed with rc=%#x!\n", rc));
+ Log(("register_chrdev() failed with rc=%#x for vboxdrv!\n", rc));
return rc;
}
+ if (DEVICE_MAJOR_SYS != 0)
+ g_iModuleMajorSys = DEVICE_MAJOR_SYS;
+ else
+ g_iModuleMajorSys = rc;
- /*
- * Save returned module major number
- */
- if (DEVICE_MAJOR != 0)
- g_iModuleMajor = DEVICE_MAJOR;
+ /* /dev/vboxdrvu */
+ /** @todo Use a minor number of this bugger (not sure if this code is used
+ * though, so not bothering right now.) */
+ g_iModuleMajorUsr = DEVICE_MAJOR_USR;
+ rc = register_chrdev((dev_t)g_iModuleMajorUsr, DEVICE_NAME_USR, &gFileOpsVBoxDrvUsr);
+ if (rc < 0)
+ {
+ Log(("register_chrdev() failed with rc=%#x for vboxdrv!\n", rc));
+ return rc;
+ }
+ if (DEVICE_MAJOR_USR != 0)
+ g_iModuleMajorUsr = DEVICE_MAJOR_USR;
else
- g_iModuleMajor = rc;
+ g_iModuleMajorUsr = rc;
rc = 0;
# ifdef CONFIG_DEVFS_FS
/*
* Register a device entry
*/
- if (devfs_mk_cdev(MKDEV(DEVICE_MAJOR, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME) != 0)
+ if ( devfs_mk_cdev(MKDEV(DEVICE_MAJOR_SYS, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME_SYS) != 0
+ || devfs_mk_cdev(MKDEV(DEVICE_MAJOR_USR, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME_USR) != 0)
{
Log(("devfs_register failed!\n"));
rc = -EINVAL;
@@ -329,10 +391,10 @@ static int __init VBoxDrvLinuxInit(void)
if (rc == 0)
#endif
{
- printk(KERN_INFO DEVICE_NAME ": TSC mode is %s, kernel timer mode is 'normal'.\n",
+ printk(KERN_INFO "vboxdrv: TSC mode is %s, kernel timer mode is 'normal'.\n",
g_DevExt.pGip->u32Mode == SUPGIPMODE_SYNC_TSC ? "'synchronous'" : "'asynchronous'");
LogFlow(("VBoxDrv::ModuleInit returning %#x\n", rc));
- printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "
+ printk(KERN_DEBUG "vboxdrv: Successfully loaded version "
VBOX_VERSION_STRING " (interface " RT_XSTR(SUPDRV_IOC_VERSION) ").\n");
return rc;
}
@@ -353,15 +415,18 @@ static int __init VBoxDrvLinuxInit(void)
* Failed, cleanup and return the error code.
*/
#if defined(CONFIG_DEVFS_FS) && !defined(CONFIG_VBOXDRV_AS_MISC)
- devfs_remove(DEVICE_NAME);
+ devfs_remove(DEVICE_NAME_SYS);
+ devfs_remove(DEVICE_NAME_USR);
#endif
}
#ifdef CONFIG_VBOXDRV_AS_MISC
- misc_deregister(&gMiscDevice);
- Log(("VBoxDrv::ModuleInit returning %#x (minor:%d)\n", rc, gMiscDevice.minor));
+ misc_deregister(&gMiscDeviceSys);
+ misc_deregister(&gMiscDeviceUsr);
+ Log(("VBoxDrv::ModuleInit returning %#x (minor:%d & %d)\n", rc, gMiscDeviceSys.minor, gMiscDeviceUsr.minor));
#else
- unregister_chrdev(g_iModuleMajor, DEVICE_NAME);
- Log(("VBoxDrv::ModuleInit returning %#x (major:%d)\n", rc, g_iModuleMajor));
+ unregister_chrdev(g_iModuleMajorUsr, DEVICE_NAME_USR);
+ unregister_chrdev(g_iModuleMajorSys, DEVICE_NAME_SYS);
+ Log(("VBoxDrv::ModuleInit returning %#x (major:%d & %d)\n", rc, g_iModuleMajorSys, g_iModuleMajorUsr));
#endif
return rc;
}
@@ -386,19 +451,26 @@ static void __exit VBoxDrvLinuxUnload(void)
* opened, at least we'll blindly assume that here.
*/
#ifdef CONFIG_VBOXDRV_AS_MISC
- rc = misc_deregister(&gMiscDevice);
+ rc = misc_deregister(&gMiscDeviceUsr);
+ if (rc < 0)
+ {
+ Log(("misc_deregister failed with rc=%#x on vboxdrvu\n", rc));
+ }
+ rc = misc_deregister(&gMiscDeviceSys);
if (rc < 0)
{
- Log(("misc_deregister failed with rc=%#x\n", rc));
+ Log(("misc_deregister failed with rc=%#x on vboxdrv\n", rc));
}
#else /* !CONFIG_VBOXDRV_AS_MISC */
# ifdef CONFIG_DEVFS_FS
/*
* Unregister a device entry
*/
- devfs_remove(DEVICE_NAME);
+ devfs_remove(DEVICE_NAME_USR);
+ devfs_remove(DEVICE_NAME_SYS);
# endif /* devfs */
- unregister_chrdev(g_iModuleMajor, DEVICE_NAME);
+ unregister_chrdev(g_iModuleMajorUsr, DEVICE_NAME_USR);
+ unregister_chrdev(g_iModuleMajorSys, DEVICE_NAME_SYS);
#endif /* !CONFIG_VBOXDRV_AS_MISC */
/*
@@ -410,12 +482,13 @@ static void __exit VBoxDrvLinuxUnload(void)
/**
- * Device open. Called on open /dev/vboxdrv
+ * Common open code.
*
- * @param pInode Pointer to inode info structure.
- * @param pFilp Associated file pointer.
+ * @param pInode Pointer to inode info structure.
+ * @param pFilp Associated file pointer.
+ * @param fUnrestricted Indicates which device node which was opened.
*/
-static int VBoxDrvLinuxCreate(struct inode *pInode, struct file *pFilp)
+static int vboxdrvLinuxCreateCommon(struct inode *pInode, struct file *pFilp, bool fUnrestricted)
{
int rc;
PSUPDRVSESSION pSession;
@@ -423,9 +496,10 @@ static int VBoxDrvLinuxCreate(struct inode *pInode, struct file *pFilp)
#ifdef VBOX_WITH_HARDENING
/*
- * Only root is allowed to access the device, enforce it!
+ * Only root is allowed to access the unrestricted device, enforce it!
*/
- if (vboxdrvLinuxEuid() != 0 /* root */ )
+ if ( fUnrestricted
+ && vboxdrvLinuxEuid() != 0 /* root */ )
{
Log(("VBoxDrvLinuxCreate: euid=%d, expected 0 (root)\n", vboxdrvLinuxEuid()));
return -EPERM;
@@ -435,7 +509,7 @@ static int VBoxDrvLinuxCreate(struct inode *pInode, struct file *pFilp)
/*
* Call common code for the rest.
*/
- rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
+ rc = supdrvCreateSession(&g_DevExt, true /* fUser */, fUnrestricted, &pSession);
if (!rc)
{
pSession->Uid = vboxdrvLinuxUid();
@@ -451,6 +525,20 @@ static int VBoxDrvLinuxCreate(struct inode *pInode, struct file *pFilp)
}
+/** /dev/vboxdrv. */
+static int VBoxDrvLinuxCreateSys(struct inode *pInode, struct file *pFilp)
+{
+ return vboxdrvLinuxCreateCommon(pInode, pFilp, true);
+}
+
+
+/** /dev/vboxdrvu. */
+static int VBoxDrvLinuxCreateUsr(struct inode *pInode, struct file *pFilp)
+{
+ return vboxdrvLinuxCreateCommon(pInode, pFilp, false);
+}
+
+
/**
* Close device.
*
@@ -461,7 +549,7 @@ static int VBoxDrvLinuxClose(struct inode *pInode, struct file *pFilp)
{
Log(("VBoxDrvLinuxClose: pFilp=%p pSession=%p pid=%d/%d %s\n",
pFilp, pFilp->private_data, RTProcSelf(), current->pid, current->comm));
- supdrvCloseSession(&g_DevExt, (PSUPDRVSESSION)pFilp->private_data);
+ supdrvSessionRelease((PSUPDRVSESSION)pFilp->private_data);
pFilp->private_data = NULL;
return 0;
}
@@ -533,27 +621,31 @@ static long VBoxDrvLinuxIOCtl(struct file *pFilp, unsigned int uCmd, unsigned lo
static int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
#endif
{
+ PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFilp->private_data;
+
/*
* Deal with the two high-speed IOCtl that takes it's arguments from
* the session and iCmd, and only returns a VBox status code.
*/
#ifdef HAVE_UNLOCKED_IOCTL
- if (RT_LIKELY( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN
- || uCmd == SUP_IOCTL_FAST_DO_HWACC_RUN
- || uCmd == SUP_IOCTL_FAST_DO_NOP))
- return supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, (PSUPDRVSESSION)pFilp->private_data);
- return VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg);
+ if (RT_LIKELY( ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN
+ || uCmd == SUP_IOCTL_FAST_DO_HM_RUN
+ || uCmd == SUP_IOCTL_FAST_DO_NOP)
+ && pSession->fUnrestricted == true))
+ return supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, pSession);
+ return VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg, pSession);
#else /* !HAVE_UNLOCKED_IOCTL */
int rc;
unlock_kernel();
- if (RT_LIKELY( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN
- || uCmd == SUP_IOCTL_FAST_DO_HWACC_RUN
- || uCmd == SUP_IOCTL_FAST_DO_NOP))
- rc = supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, (PSUPDRVSESSION)pFilp->private_data);
+ if (RT_LIKELY( ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN
+ || uCmd == SUP_IOCTL_FAST_DO_HM_RUN
+ || uCmd == SUP_IOCTL_FAST_DO_NOP)
+ && pSession->fUnrestricted == true))
+ rc = supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, pSession);
else
- rc = VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg);
+ rc = VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg, pSession);
lock_kernel();
return rc;
#endif /* !HAVE_UNLOCKED_IOCTL */
@@ -566,8 +658,9 @@ static int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned
* @param pFilp Associated file pointer.
* @param uCmd The function specified to ioctl().
* @param ulArg The argument specified to ioctl().
+ * @param pSession The session instance.
*/
-static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
+static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg, PSUPDRVSESSION pSession)
{
int rc;
SUPREQHDR Hdr;
@@ -620,7 +713,7 @@ static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned
/*
* Process the IOCtl.
*/
- rc = supdrvIOCtl(uCmd, &g_DevExt, (PSUPDRVSESSION)pFilp->private_data, pHdr);
+ rc = supdrvIOCtl(uCmd, &g_DevExt, pSession, pHdr);
/*
* Copy ioctl data and output buffer back to user space.
diff --git a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c
index 0aaea1a1..20930520 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c
+++ b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.mod.c
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp b/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
index 46281442..e3d1a349 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
+++ b/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -30,6 +30,7 @@
#define LOG_GROUP LOG_GROUP_SUP
#ifdef IN_SUP_HARDENED_R3
# undef DEBUG /* Warning: disables RT_STRICT */
+# undef RT_STRICT
# define LOG_DISABLED
/** @todo RTLOGREL_DISABLED */
# include <iprt/log.h>
@@ -61,8 +62,10 @@
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
-/** Unix Device name. */
-#define DEVICE_NAME "/dev/vboxdrv"
+/** System device name. */
+#define DEVICE_NAME_SYS "/dev/vboxdrv"
+/** User device name. */
+#define DEVICE_NAME_USR "/dev/vboxdrvu"
/* define MADV_DONTFORK if it's missing from the system headers. */
#ifndef MADV_DONTFORK
@@ -71,7 +74,7 @@
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
{
/*
* Nothing to do if pre-inited.
@@ -92,13 +95,14 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* Try open the device.
*/
- int hDevice = open(DEVICE_NAME, O_RDWR, 0);
+ const char *pszDeviceNm = fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR;
+ int hDevice = open(pszDeviceNm, O_RDWR, 0);
if (hDevice < 0)
{
/*
* Try load the device.
*/
- hDevice = open(DEVICE_NAME, O_RDWR, 0);
+ hDevice = open(pszDeviceNm, O_RDWR, 0);
if (hDevice < 0)
{
int rc;
@@ -111,7 +115,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
case ENOENT: rc = VERR_VM_DRIVER_NOT_INSTALLED; break;
default: rc = VERR_VM_DRIVER_OPEN_ERROR; break;
}
- LogRel(("Failed to open \"%s\", errno=%d, rc=%Rrc\n", DEVICE_NAME, errno, rc));
+ LogRel(("Failed to open \"%s\", errno=%d, rc=%Rrc\n", pszDeviceNm, errno, rc));
return rc;
}
}
@@ -132,7 +136,8 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* We're done.
*/
- pThis->hDevice = hDevice;
+ pThis->hDevice = hDevice;
+ pThis->fUnrestricted = fUnrestricted;
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c b/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c
index 15d9761f..7bc8e6d0 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c
+++ b/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/linux/files_vboxdrv b/src/VBox/HostDrivers/Support/linux/files_vboxdrv
index 4aaa9a58..064714de 100755
--- a/src/VBox/HostDrivers/Support/linux/files_vboxdrv
+++ b/src/VBox/HostDrivers/Support/linux/files_vboxdrv
@@ -75,8 +75,8 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/include/VBox/types.h=>include/VBox/types.h \
${PATH_ROOT}/include/VBox/SUPDrvMangling.h=>include/VBox/SUPDrvMangling.h \
${PATH_ROOT}/include/VBox/VBoxTpG.h=>include/VBox/VBoxTpG.h \
- ${PATH_ROOT}/include/VBox/vmm/hwacc_vmx.h=>include/VBox/vmm/hwacc_vmx.h \
- ${PATH_ROOT}/include/VBox/vmm/hwacc_svm.h=>include/VBox/vmm/hwacc_svm.h \
+ ${PATH_ROOT}/include/VBox/vmm/hm_vmx.h=>include/VBox/vmm/hm_vmx.h \
+ ${PATH_ROOT}/include/VBox/vmm/hm_svm.h=>include/VBox/vmm/hm_svm.h \
${PATH_ROOT}/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c=>linux/SUPDrv-linux.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrv.c=>SUPDrv.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvSem.c=>SUPDrvSem.c \
@@ -151,6 +151,7 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteStdOut-stub-generic.cpp=>generic/RTLogWriteStdOut-stub-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteUser-generic.cpp=>generic/RTLogWriteUser-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp=>generic/RTMpGetArraySize-generic.c \
+ ${PATH_ROOT}/src/VBox/Runtime/generic/RTMpGetCoreCount-generic.cpp=>generic/RTMpGetCoreCount-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp=>generic/RTSemEventWait-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventWaitNoResume-2-ex-generic.c \
${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \
@@ -184,6 +185,7 @@ FILES_VBOXDRV_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h=>r0drv/linux/the-linux-kernel.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c=>r0drv/linux/thread-r0drv-linux.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c=>r0drv/linux/thread2-r0drv-linux.c \
+ ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/threadctxhooks-r0drv-linux.c=>r0drv/linux/threadctxhooks-r0drv-linux.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c=>r0drv/linux/time-r0drv-linux.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c=>r0drv/linux/timer-r0drv-linux.c \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h=>r0drv/linux/waitqueue-r0drv-linux.h \
diff --git a/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp b/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
index b3927eb0..0eecf131 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
+++ b/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
@@ -150,7 +150,7 @@ DECLASM(int) VBoxDrvOpen(uint16_t sfn)
/*
* Create a new session.
*/
- rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
+ rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
if (RT_SUCCESS(rc))
{
pSession->sfn = sfn;
@@ -221,7 +221,7 @@ DECLASM(int) VBoxDrvClose(uint16_t sfn)
/*
* Close the session.
*/
- supdrvCloseSession(&g_DevExt, pSession);
+ supdrvSessionRelease(pSession);
return 0;
}
@@ -243,6 +243,9 @@ DECLASM(int) VBoxDrvIOCtlFast(uint16_t sfn, uint8_t iFunction)
while ( pSession
&& ( pSession->sfn != sfn
|| pSession->Process != Process));
+
+ if (RT_LIKELY(pSession))
+ supdrvSessionRetain(pSession);
}
RTSpinlockReleaseNoInts(g_Spinlock);
if (RT_UNLIKELY(!pSession))
@@ -255,6 +258,7 @@ DECLASM(int) VBoxDrvIOCtlFast(uint16_t sfn, uint8_t iFunction)
* Dispatch the fast IOCtl.
*/
supdrvIOCtlFast(iFunction, 0, &g_DevExt, pSession);
+ supdrvSessionRelease(pSession);
return 0;
}
@@ -276,6 +280,9 @@ DECLASM(int) VBoxDrvIOCtl(uint16_t sfn, uint8_t iCat, uint8_t iFunction, void *p
while ( pSession
&& ( pSession->sfn != sfn
|| pSession->Process != Process));
+
+ if (RT_LIKELY(pSession))
+ supdrvSessionRetain(pSession);
}
RTSpinlockReleaseNoInts(g_Spinlock);
if (!pSession)
@@ -345,12 +352,14 @@ DECLASM(int) VBoxDrvIOCtl(uint16_t sfn, uint8_t iCat, uint8_t iFunction, void *p
* Unlock and return.
*/
int rc2 = KernVMUnlock(&Lock);
- AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);
-
- Log2(("VBoxDrvIOCtl: returns %d\n", rc));
- return rc;
+ AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);s
}
- return VERR_NOT_SUPPORTED;
+ else
+ rc = VERR_NOT_SUPPORTED;
+
+ supdrvSessionRelease(pSession);
+ Log2(("VBoxDrvIOCtl: returns %d\n", rc));
+ return rc;
}
diff --git a/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def b/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def
index 420bfd61..18550ae1 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def
+++ b/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.def
@@ -4,7 +4,7 @@
;
;
-; Copyright (C) 2007 Oracle Corporation
+; Copyright (C) 2007-2010 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp b/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp
index c502b7c4..0f235eeb 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp
+++ b/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -65,7 +65,7 @@
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
{
/*
* Nothing to do if pre-inited.
@@ -100,6 +100,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
}
pThis->hDevice = hDevice;
+ pThis->fUnrestricted = true;
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c b/src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c
index a20af460..9f06939d 100644
--- a/src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c
+++ b/src/VBox/HostDrivers/Support/os2/SUPR0IdcClient-os2.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c b/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
index 6916c8bc..9b0f60b9 100644
--- a/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
+++ b/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -71,8 +71,10 @@
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
-/** The module name. */
-#define DEVICE_NAME "vboxdrv"
+/** The system device name. */
+#define DEVICE_NAME_SYS "vboxdrv"
+/** The user device name. */
+#define DEVICE_NAME_USR "vboxdrvu"
/** The module description as seen in 'modinfo'. */
#define DEVICE_DESC "VirtualBox HostDrv"
/** Maximum number of driver instances. */
@@ -196,7 +198,7 @@ static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
*/
int _init(void)
{
- LogFlowFunc((DEVICE_NAME ":_init\n"));
+ LogFlowFunc(("vboxdrv:_init\n"));
/*
* Prevent module autounloading.
@@ -205,7 +207,7 @@ int _init(void)
if (pModCtl)
pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
else
- LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
+ LogRel(("vboxdrv: failed to disable autounloading!\n"));
/*
* Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
@@ -234,31 +236,31 @@ int _init(void)
return rc; /* success */
ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
- LogRel((DEVICE_NAME ":mod_install failed! rc=%d\n", rc));
+ LogRel(("vboxdrv: mod_install failed! rc=%d\n", rc));
}
else
- LogRel((DEVICE_NAME ":failed to initialize soft state.\n"));
+ LogRel(("vboxdrv: failed to initialize soft state.\n"));
RTSpinlockDestroy(g_Spinlock);
g_Spinlock = NIL_RTSPINLOCK;
}
else
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
+ LogRel(("VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
rc = RTErrConvertToErrno(rc);
}
supdrvDeleteDevExt(&g_DevExt);
}
else
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
+ LogRel(("VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
rc = RTErrConvertToErrno(rc);
}
RTR0TermForced();
}
else
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: failed to init R0Drv\n"));
+ LogRel(("VBoxDrvSolarisAttach: failed to init R0Drv\n"));
rc = RTErrConvertToErrno(rc);
}
memset(&g_DevExt, 0, sizeof(g_DevExt));
@@ -269,7 +271,7 @@ int _init(void)
int _fini(void)
{
- LogFlowFunc((DEVICE_NAME ":_fini\n"));
+ LogFlowFunc(("vboxdrv:_fini\n"));
/*
* Undo the work we did at start (in the reverse order).
@@ -295,7 +297,7 @@ int _fini(void)
int _info(struct modinfo *pModInfo)
{
- LogFlowFunc((DEVICE_NAME ":_info\n"));
+ LogFlowFunc(("vboxdrv:_info\n"));
int e = mod_info(&g_VBoxDrvSolarisModLinkage, pModInfo);
return e;
}
@@ -311,20 +313,20 @@ int _info(struct modinfo *pModInfo)
*/
static int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
{
- LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisAttach\n"));
+ LogFlowFunc(("VBoxDrvSolarisAttach\n"));
switch (enmCmd)
{
case DDI_ATTACH:
{
int rc;
- int instance = ddi_get_instance(pDip);
#ifdef USE_SESSION_HASH
+ int instance = ddi_get_instance(pDip);
vbox_devstate_t *pState;
if (ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, instance) != DDI_SUCCESS)
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: state alloc failed\n"));
+ LogRel(("VBoxDrvSolarisAttach: state alloc failed\n"));
return DDI_FAILURE;
}
@@ -337,25 +339,31 @@ static int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
rc = ddi_prop_create(DDI_DEV_T_NONE, pDip, DDI_PROP_CANSLEEP /* kmem alloc can sleep */,
"pm-hardware-state", "needs-suspend-resume", sizeof("needs-suspend-resume"));
if (rc != DDI_PROP_SUCCESS)
- LogRel((DEVICE_NAME ":Suspend/Resume notification registration failed.\n"));
+ LogRel(("vboxdrv: Suspend/Resume notification registration failed.\n"));
/*
* Register ourselves as a character device, pseudo-driver
*/
#ifdef VBOX_WITH_HARDENING
- rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO,
+ rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_SYS, S_IFCHR, 0 /*minor*/, DDI_PSEUDO,
0, NULL, NULL, 0600);
#else
- rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO,
+ rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_SYS, S_IFCHR, 0 /*minor*/, DDI_PSEUDO,
0, "none", "none", 0666);
#endif
if (rc == DDI_SUCCESS)
{
+ rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_USR, S_IFCHR, 1 /*minor*/, DDI_PSEUDO,
+ 0, "none", "none", 0666);
+ if (rc == DDI_SUCCESS)
+ {
#ifdef USE_SESSION_HASH
- pState->pDip = pDip;
+ pState->pDip = pDip;
#endif
- ddi_report_dev(pDip);
- return DDI_SUCCESS;
+ ddi_report_dev(pDip);
+ return DDI_SUCCESS;
+ }
+ ddi_remove_minor_node(pDip, NULL);
}
return DDI_FAILURE;
@@ -371,7 +379,7 @@ static int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
RTSemFastMutexRelease(g_DevExt.mtxGip);
#endif
RTPowerSignalEvent(RTPOWEREVENT_RESUME);
- LogFlow((DEVICE_NAME ": Awakened from suspend.\n"));
+ LogFlow(("vboxdrv: Awakened from suspend.\n"));
return DDI_SUCCESS;
}
@@ -393,7 +401,7 @@ static int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
*/
static int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
{
- LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisDetach\n"));
+ LogFlowFunc(("VBoxDrvSolarisDetach\n"));
switch (enmCmd)
{
case DDI_DETACH:
@@ -420,7 +428,7 @@ static int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
RTSemFastMutexRelease(g_DevExt.mtxGip);
#endif
RTPowerSignalEvent(RTPOWEREVENT_SUSPEND);
- LogFlow((DEVICE_NAME ": Falling to suspend mode.\n"));
+ LogFlow(("vboxdrv: Falling to suspend mode.\n"));
return DDI_SUCCESS;
}
@@ -433,13 +441,22 @@ static int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
/**
- * User context entry points
+ * open() worker.
*/
static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
{
- int rc;
+ const bool fUnrestricted = getminor(*pDev) == 0;
PSUPDRVSESSION pSession;
- LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev));
+ int rc;
+
+ LogFlowFunc(("VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev));
+
+ /*
+ * Validate input
+ */
+ if ( (getminor(*pDev) != 0 && getminor(*pDev) != 1)
+ || fType != OTYP_CHR)
+ return EINVAL; /* See mmopen for precedent. */
#ifndef USE_SESSION_HASH
/*
@@ -461,14 +478,14 @@ static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
}
if (!pState)
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisOpen: too many open instances.\n"));
+ LogRel(("VBoxDrvSolarisOpen: too many open instances.\n"));
return ENXIO;
}
/*
* Create a new session.
*/
- rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
+ rc = supdrvCreateSession(&g_DevExt, true /* fUser */, fUnrestricted, &pSession);
if (RT_SUCCESS(rc))
{
pSession->Uid = crgetruid(pCred);
@@ -476,8 +493,8 @@ static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
pState->pSession = pSession;
*pDev = makedevice(getmajor(*pDev), iOpenInstance);
- LogFlow((DEVICE_NAME ":VBoxDrvSolarisOpen: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
- *pDev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
+ LogFlow(("VBoxDrvSolarisOpen: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
+ *pDev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
return 0;
}
@@ -490,7 +507,7 @@ static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
* Sessions in Solaris driver are mostly useless. It's however needed
* in VBoxDrvSolarisIOCtlSlow() while calling supdrvIOCtl()
*/
- rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
+ rc = supdrvCreateSession(&g_DevExt, true /* fUser */, fUnrestricted, &pSession);
if (RT_SUCCESS(rc))
{
unsigned iHash;
@@ -501,12 +518,13 @@ static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
/*
* Insert it into the hash table.
*/
+# error "Only one entry per process!"
iHash = SESSION_HASH(pSession->Process);
RTSpinlockAcquire(g_Spinlock);
pSession->pNextHash = g_apSessionHashTab[iHash];
g_apSessionHashTab[iHash] = pSession;
RTSpinlockReleaseNoInts(g_Spinlock);
- LogFlow((DEVICE_NAME ":VBoxDrvSolarisOpen success\n"));
+ LogFlow(("VBoxDrvSolarisOpen success\n"));
}
int instance;
@@ -519,7 +537,7 @@ static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
if (instance >= DEVICE_MAXINSTANCES)
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisOpen: All instances exhausted\n"));
+ LogRel(("VBoxDrvSolarisOpen: All instances exhausted\n"));
return ENXIO;
}
@@ -532,7 +550,7 @@ static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
{
- LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisClose: Dev=%#x\n", Dev));
+ LogFlowFunc(("VBoxDrvSolarisClose: Dev=%#x\n", Dev));
#ifndef USE_SESSION_HASH
/*
@@ -541,7 +559,7 @@ static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));
if (!pState)
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev)));
+ LogRel(("VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev)));
return EFAULT;
}
@@ -551,10 +569,10 @@ static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
if (!pSession)
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
+ LogRel(("VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
return EFAULT;
}
- LogFlow((DEVICE_NAME ":VBoxDrvSolarisClose: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
+ LogFlow(("VBoxDrvSolarisClose: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
Dev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
#else
@@ -596,8 +614,7 @@ static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
RTSpinlockReleaseNoInts(g_Spinlock);
if (!pSession)
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n",
- (int)Process));
+ LogRel(("VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n", (int)Process));
return EFAULT;
}
#endif
@@ -605,21 +622,21 @@ static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
/*
* Close the session.
*/
- supdrvCloseSession(&g_DevExt, pSession);
+ supdrvSessionRelease(pSession);
return 0;
}
static int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
{
- LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisRead"));
+ LogFlowFunc(("VBoxDrvSolarisRead"));
return 0;
}
static int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
{
- LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisWrite"));
+ LogFlowFunc(("VBoxDrvSolarisWrite"));
return 0;
}
@@ -645,36 +662,34 @@ static int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cre
vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));
if (!pState)
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev)));
+ LogRel(("VBoxDrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev)));
return EINVAL;
}
PSUPDRVSESSION pSession = pState->pSession;
if (!pSession)
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
+ LogRel(("VBoxDrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
return DDI_SUCCESS;
}
#else
const RTPROCESS Process = RTProcSelf();
const unsigned iHash = SESSION_HASH(Process);
PSUPDRVSESSION pSession;
+ const bool fUnrestricted = getminor(Dev) == 0;
/*
* Find the session.
*/
RTSpinlockAcquire(g_Spinlock);
pSession = g_apSessionHashTab[iHash];
- if (pSession && pSession->Process != Process)
- {
- do pSession = pSession->pNextHash;
- while (pSession && pSession->Process != Process);
- }
+ while (pSession && pSession->Process != Process && pSession->fUnrestricted == fUnrestricted);
+ pSession = pSession->pNextHash;
RTSpinlockReleaseNoInts(g_Spinlock);
if (!pSession)
{
- LogRel((DEVICE_NAME ":VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n",
- (int)Process, Cmd));
+ LogRel(("VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x Dev=%#x\n",
+ (int)Process, Cmd, (int)Dev));
return EINVAL;
}
#endif
@@ -683,9 +698,10 @@ static int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cre
* Deal with the two high-speed IOCtl that takes it's arguments from
* the session and iCmd, and only returns a VBox status code.
*/
- if ( Cmd == SUP_IOCTL_FAST_DO_RAW_RUN
- || Cmd == SUP_IOCTL_FAST_DO_HWACC_RUN
- || Cmd == SUP_IOCTL_FAST_DO_NOP)
+ if ( ( Cmd == SUP_IOCTL_FAST_DO_RAW_RUN
+ || Cmd == SUP_IOCTL_FAST_DO_HM_RUN
+ || Cmd == SUP_IOCTL_FAST_DO_NOP)
+ && pSession->fUnrestricted)
{
*pVal = supdrvIOCtlFast(Cmd, pArgs, &g_DevExt, pSession);
return 0;
@@ -731,18 +747,18 @@ static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode,
*/
if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(StackBuf.Hdr)))
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
+ LogRel(("VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
return EINVAL;
}
rc = ddi_copyin((void *)iArg, &StackBuf.Hdr, sizeof(StackBuf.Hdr), Mode);
if (RT_UNLIKELY(rc))
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
+ LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
return EFAULT;
}
if (RT_UNLIKELY((StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
+ LogRel(("VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
return EINVAL;
}
cbBuf = RT_MAX(StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut);
@@ -750,7 +766,7 @@ static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode,
|| StackBuf.Hdr.cbOut < sizeof(StackBuf.Hdr)
|| cbBuf > _1M*16))
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
+ LogRel(("VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
return EINVAL;
}
@@ -764,14 +780,14 @@ static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode,
pHdr = RTMemTmpAlloc(cbBuf);
if (RT_UNLIKELY(!pHdr))
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
+ LogRel(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
return ENOMEM;
}
}
rc = ddi_copyin((void *)iArg, pHdr, cbBuf, Mode);
if (RT_UNLIKELY(rc))
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
+ LogRel(("VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
if (pHdr != &StackBuf.Hdr)
RTMemFree(pHdr);
return EFAULT;
@@ -790,14 +806,14 @@ static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode,
uint32_t cbOut = pHdr->cbOut;
if (RT_UNLIKELY(cbOut > cbBuf))
{
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
+ LogRel(("VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
cbOut = cbBuf;
}
rc = ddi_copyout(pHdr, (void *)iArg, cbOut, Mode);
if (RT_UNLIKELY(rc != 0))
{
/* this is really bad */
- LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
+ LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
rc = EFAULT;
}
}
@@ -1177,6 +1193,10 @@ RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
va_list args;
char szMsg[512];
+ /* cmn_err() acquires adaptive mutexes. Not preemption safe, see @bugref{6657}. */
+ if (!RTThreadPreemptIsEnabled(NIL_RTTHREAD))
+ return 0;
+
va_start(args, pszFormat);
RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, args);
va_end(args);
diff --git a/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp b/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp
index 0cb71dca..602854f4 100644
--- a/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp
+++ b/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -52,6 +52,7 @@
#include <sys/fcntl.h>
#include <sys/ioctl.h>
+#include <sys/zone.h>
#include <fcntl.h>
#include <errno.h>
@@ -59,17 +60,24 @@
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
+#include <zone.h>
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
-/** Solaris device link. */
-#define DEVICE_NAME "/dev/vboxdrv"
+/** Solaris device link - system. */
+#define DEVICE_NAME_SYS "/devices/pseudo/vboxdrv@0:vboxdrv"
+/** Solaris device link - user. */
+#define DEVICE_NAME_USR "/devices/pseudo/vboxdrv@0:vboxdrvu"
+/** Solaris device link - system (non-global zone). */
+#define DEVICE_NAME_SYS_ZONE "/dev/vboxdrv"
+/** Solaris device link - user (non-global zone). */
+#define DEVICE_NAME_USR_ZONE "/dev/vboxdrvu"
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
{
/*
* Nothing to do if pre-inited.
@@ -101,7 +109,12 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* Try to open the device.
*/
- int hDevice = open(DEVICE_NAME, O_RDWR, 0);
+ const char *pszDeviceNm;
+ if (getzoneid() == GLOBAL_ZONEID)
+ pszDeviceNm = fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR;
+ else
+ pszDeviceNm = fUnrestricted ? DEVICE_NAME_SYS_ZONE : DEVICE_NAME_USR_ZONE;
+ int hDevice = open(pszDeviceNm, O_RDWR, 0);
if (hDevice < 0)
{
int rc;
@@ -113,7 +126,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
case ENOENT: rc = VERR_VM_DRIVER_NOT_INSTALLED; break;
default: rc = VERR_VM_DRIVER_OPEN_ERROR; break;
}
- LogRel(("Failed to open \"%s\", errno=%d, rc=%Rrc\n", DEVICE_NAME, errno, rc));
+ LogRel(("Failed to open \"%s\", errno=%d, rc=%Rrc\n", pszDeviceNm, errno, rc));
return rc;
}
@@ -133,7 +146,8 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
return rc;
}
- pThis->hDevice = hDevice;
+ pThis->hDevice = hDevice;
+ pThis->fUnrestricted = fUnrestricted;
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c b/src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c
index 033fcdec..c7ca7b3f 100644
--- a/src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c
+++ b/src/VBox/HostDrivers/Support/solaris/SUPR0IdcClient-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/solaris/load.sh b/src/VBox/HostDrivers/Support/solaris/load.sh
index fb204408..985c3459 100755
--- a/src/VBox/HostDrivers/Support/solaris/load.sh
+++ b/src/VBox/HostDrivers/Support/solaris/load.sh
@@ -26,7 +26,7 @@
#
DRVNAME="vboxdrv"
-DRIVERS_USING_IT="vboxusbmon vboxusb vboxnet vboxflt vboxbow"
+DRIVERS_USING_IT="vboxusb vboxusbmon vboxnet vboxflt vboxbow"
DRVFILE=`dirname "$0"`
DRVFILE=`cd "$DRVFILE" && pwd`
@@ -43,7 +43,10 @@ fi
SUDO=sudo
#set -x
-# Unload driver that may depend on the driver we're going to (re-)load
+# Disable the zone access service.
+$SUDO svcadm disable svc:/application/virtualbox/zoneaccess:default
+
+# Unload driver that may depend on the driver we're going to (re-)load
# as well as the driver itself.
for drv in $DRIVERS_USING_IT $DRVNAME;
do
@@ -64,9 +67,9 @@ done
# Reconfigure the driver so it get a major number.
#
# Note! We have to copy the driver and config files to somewhere the kernel can
-# find them. It is searched for as drv/${DRVNAME}.conf in
-# kobj_module_path, which is usually:
-# /platform/i86pc/kernel /kernel /usr/kernel
+# find them. It is searched for as drv/${DRVNAME}.conf in
+# kobj_module_path, which is usually:
+# /platform/i86pc/kernel /kernel /usr/kernel
# To try prevent bad drivers from being loaded on the next boot, we remove
# always the files.
#
diff --git a/src/VBox/HostDrivers/Support/solaris/vboxdrv.conf b/src/VBox/HostDrivers/Support/solaris/vboxdrv.conf
index ed6f9cf4..cd136110 100644
--- a/src/VBox/HostDrivers/Support/solaris/vboxdrv.conf
+++ b/src/VBox/HostDrivers/Support/solaris/vboxdrv.conf
@@ -1,11 +1,10 @@
-# $Revision: $
+# $Id: vboxdrv.conf $
## @file
-#
-# OpenSolaris Host Driver Configuration
+# VirtualBox Solaris Host Driver Configuration.
#
#
-# Copyright (C) 2007-2010 Oracle Corporation
+# Copyright (C) 2007-2012 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -31,3 +30,4 @@
# directory). After copying execute add_drv vboxdrv.
#
name="vboxdrv" parent="pseudo" instance=0;
+
diff --git a/src/VBox/HostDrivers/Support/testcase/Makefile.kmk b/src/VBox/HostDrivers/Support/testcase/Makefile.kmk
index 4016e159..534f426f 100644
--- a/src/VBox/HostDrivers/Support/testcase/Makefile.kmk
+++ b/src/VBox/HostDrivers/Support/testcase/Makefile.kmk
@@ -44,6 +44,8 @@ PROGRAMS += \
tstSupLoadModule \
tstSupSem \
tstSupSem-Zombie
+PROGRAMS.win += \
+ tstNtQueryStuff
endif # VBOX_WITH_TESTCASES
SUPInstall_TEMPLATE = VBOXR3EXE
@@ -71,6 +73,10 @@ tstInit_SOURCES = tstInit.cpp
tstLow_TEMPLATE = VBOXR3TSTEXE
tstLow_SOURCES = tstLow.cpp
+tstNtQueryStuff_TEMPLATE = VBOXR3TSTEXE
+tstNtQueryStuff_SDKS = VBOX_NTDLL
+tstNtQueryStuff_SOURCES = tstNtQueryStuff.cpp
+
tstPin_TEMPLATE = VBOXR3TSTEXE
tstPin_SOURCES = tstPin.cpp
diff --git a/src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp b/src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp
index f2f2b81c..81205d31 100644
--- a/src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/SUPLoggerCtl.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp b/src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp
index a0030808..be9f72cb 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstContiguous.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp b/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
index 97ace8c7..129007a9 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -96,7 +96,8 @@ int main(int argc, char **argv)
{
if (g_pSUPGlobalInfoPage)
{
- RTPrintf("tstGIP-2: u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u32Mode=%d (%s) u32Version=%#x\n",
+ RTPrintf("tstGIP-2: cCpus=%d u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u32Mode=%d (%s) u32Version=%#x\n",
+ g_pSUPGlobalInfoPage->cCpus,
g_pSUPGlobalInfoPage->u32UpdateHz,
g_pSUPGlobalInfoPage->u32UpdateIntervalNS,
g_pSUPGlobalInfoPage->u64NanoTSLastUpdateHz,
@@ -108,16 +109,16 @@ int main(int argc, char **argv)
RTPrintf(fHex
? "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz TSC Interval History...\n"
: "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz TSC Interval History...\n");
- static SUPGIPCPU s_aaCPUs[2][RT_ELEMENTS(g_pSUPGlobalInfoPage->aCPUs)];
+ static SUPGIPCPU s_aaCPUs[2][256];
for (uint32_t i = 0; i < cIterations; i++)
{
/* copy the data */
- memcpy(&s_aaCPUs[i & 1][0], &g_pSUPGlobalInfoPage->aCPUs[0], sizeof(g_pSUPGlobalInfoPage->aCPUs));
+ memcpy(&s_aaCPUs[i & 1][0], &g_pSUPGlobalInfoPage->aCPUs[0], g_pSUPGlobalInfoPage->cCpus * sizeof(g_pSUPGlobalInfoPage->aCPUs[0]));
/* display it & find something to spin on. */
uint32_t u32TransactionId = 0;
uint32_t volatile *pu32TransactionId = NULL;
- for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_pSUPGlobalInfoPage->aCPUs); iCpu++)
+ for (unsigned iCpu = 0; iCpu < g_pSUPGlobalInfoPage->cCpus; iCpu++)
if ( g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz > 0
&& g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz != _4G + 1)
{
diff --git a/src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp b/src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp
index 1af3d73b..15274cf7 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstGetPagingMode.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/testcase/tstInit.cpp b/src/VBox/HostDrivers/Support/testcase/tstInit.cpp
index bdbe4613..bcb4028c 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstInit.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstInit.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/testcase/tstInt.cpp b/src/VBox/HostDrivers/Support/testcase/tstInt.cpp
index 9a522601..27e426ae 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstInt.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstInt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/testcase/tstLow.cpp b/src/VBox/HostDrivers/Support/testcase/tstLow.cpp
index 39058924..27a840d6 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstLow.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstLow.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -80,7 +80,7 @@ int main(int argc, char **argv)
for (uint8_t *pu8 = (uint8_t *)pvPages0 + iPage * PAGE_SIZE, *pu8End = pu8 + PAGE_SIZE; pu8 < pu8End; pu8++)
if (*pu8 != (uint8_t)iPage)
{
- RTPrintf("tstLow: error: invalid page content %02x != %02x. iPage=%p off=%#x\n",
+ RTPrintf("tstLow: error: invalid page content %02x != %02x. iPage=%u off=%#x\n",
*pu8, (uint8_t)iPage, iPage, (uintptr_t)pu8 & PAGE_OFFSET_MASK);
rcRet++;
}
diff --git a/src/VBox/HostDrivers/Support/testcase/tstNtQueryStuff.cpp b/src/VBox/HostDrivers/Support/testcase/tstNtQueryStuff.cpp
new file mode 100644
index 00000000..02f5bf30
--- /dev/null
+++ b/src/VBox/HostDrivers/Support/testcase/tstNtQueryStuff.cpp
@@ -0,0 +1,452 @@
+/* $Id: tstNtQueryStuff.cpp $ */
+/** @file
+ * SUP Testcase - Exploring some NT Query APIs.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
+#include <Windows.h>
+#include <winternl.h>
+
+typedef enum
+{
+ MemoryBasicInformation = 0,
+ MemoryWorkingSetList,
+ MemorySectionName,
+ MemoryBasicVlmInformation
+} MEMORY_INFORMATION_CLASS;
+
+typedef struct
+{
+ UNICODE_STRING SectionFileName;
+ WCHAR NameBuffer[ANYSIZE_ARRAY];
+} MEMORY_SECTION_NAME;
+
+extern "C"
+NTSYSAPI NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE hProcess,
+ IN LPCVOID pvWhere,
+ IN MEMORY_INFORMATION_CLASS MemoryInfo,
+ OUT PVOID pvBuf,
+ IN SIZE_T cbBuf,
+ OUT PSIZE_T pcbReturned OPTIONAL);
+
+#define ProcessDebugPort ((PROCESSINFOCLASS)7 )
+#define ProcessHandleCount ((PROCESSINFOCLASS)20)
+#define ProcessWow64Information ((PROCESSINFOCLASS)26)
+#define ProcessImageFileName ((PROCESSINFOCLASS)27)
+#define ProcessDebugObjectHandle ((PROCESSINFOCLASS)30)
+#define ProcessExecuteFlags ((PROCESSINFOCLASS)34)
+#define ProcessImageFileNameWin32 ((PROCESSINFOCLASS)43)
+#define ProcessImageFileMapping ((PROCESSINFOCLASS)44)
+
+
+#include <iprt/test.h>
+#include <iprt/string.h>
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+typedef struct FLAGDESC
+{
+ ULONG f;
+ const char *psz;
+} FLAGDESC;
+typedef const FLAGDESC *PCFLAGDESC;
+
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+static RTTEST g_hTest = NIL_RTTEST;
+static HANDLE g_hProcess = NULL;
+
+
+static char *stringifyAppend(char *pszBuf, size_t *pcbBuf, const char *pszAppend, bool fWithSpace)
+{
+ size_t cchAppend = strlen(pszAppend);
+ if (cchAppend + 1 + fWithSpace <= *pcbBuf)
+ {
+ if (fWithSpace)
+ {
+ *pszBuf++ = ' ';
+ *pcbBuf += 1;
+ }
+ memcpy(pszBuf, pszAppend, cchAppend + 1);
+ *pcbBuf -= cchAppend;
+ pszBuf += cchAppend;
+ }
+
+ return pszBuf;
+}
+
+
+static char *stringifyAppendUnknownFlags(uint32_t fFlags, char *pszBuf, size_t *pcbBuf, bool fWithSpace)
+{
+ for (unsigned iBit = 0; iBit < 32; iBit++)
+ if (fFlags & RT_BIT_32(iBit))
+ {
+ char szTmp[32]; /* lazy bird */
+ RTStrPrintf(szTmp, sizeof(szTmp), "BIT(%d)", iBit);
+ pszBuf = stringifyAppend(pszBuf, pcbBuf, szTmp, fWithSpace);
+ fWithSpace = true;
+ }
+
+ return pszBuf;
+}
+
+
+static char *stringifyFlags(uint32_t fFlags, char *pszBuf, size_t cbBuf, PCFLAGDESC paFlagDesc, size_t cFlagDesc)
+{
+ char *pszBufStart = pszBuf;
+ if (fFlags)
+ {
+ for (size_t i = 0; i < cFlagDesc; i++)
+ {
+ if (fFlags & paFlagDesc[i].f)
+ {
+ fFlags &= ~paFlagDesc[i].f;
+ pszBuf = stringifyAppend(pszBuf, &cbBuf, paFlagDesc[i].psz, pszBuf != pszBufStart);
+ }
+ }
+
+ if (fFlags)
+ stringifyAppendUnknownFlags(fFlags, pszBuf, &cbBuf, pszBuf != pszBufStart);
+ }
+ else
+ {
+ pszBuf[0] = '0';
+ pszBuf[1] = '\0';
+ }
+ return pszBufStart;
+}
+
+
+static char *stringifyMemType(uint32_t fType, char *pszBuf, size_t cbBuf)
+{
+ static const FLAGDESC s_aMemTypes[] =
+ {
+ { MEM_PRIVATE, "PRIVATE" },
+ { MEM_MAPPED, "MAPPED" },
+ { MEM_IMAGE, "IMAGE" },
+ };
+ return stringifyFlags(fType, pszBuf, cbBuf, s_aMemTypes, RT_ELEMENTS(s_aMemTypes));
+}
+
+
+static char *stringifyMemState(uint32_t fState, char *pszBuf, size_t cbBuf)
+{
+ static const FLAGDESC s_aMemStates[] =
+ {
+ { MEM_FREE, "FREE" },
+ { MEM_COMMIT, "COMMIT" },
+ { MEM_RESERVE, "RESERVE" },
+ { MEM_DECOMMIT, "DECOMMMIT" },
+ };
+ return stringifyFlags(fState, pszBuf, cbBuf, s_aMemStates, RT_ELEMENTS(s_aMemStates));
+}
+
+
+static char *stringifyMemProt(uint32_t fProt, char *pszBuf, size_t cbBuf)
+{
+ static const FLAGDESC s_aProtections[] =
+ {
+ { PAGE_NOACCESS, "NOACCESS" },
+ { PAGE_READONLY, "READONLY" },
+ { PAGE_READWRITE, "READWRITE" },
+ { PAGE_WRITECOPY, "WRITECOPY" },
+ { PAGE_EXECUTE, "EXECUTE" },
+ { PAGE_EXECUTE_READ, "EXECUTE_READ" },
+ { PAGE_EXECUTE_READWRITE, "EXECUTE_READWRITE" },
+ { PAGE_EXECUTE_WRITECOPY, "EXECUTE_WRITECOPY" },
+ { PAGE_GUARD, "GUARD" },
+ { PAGE_NOCACHE, "NOCACHE" },
+ { PAGE_WRITECOMBINE, "WRITECOMBINE" },
+
+ };
+ return stringifyFlags(fProt, pszBuf, cbBuf, s_aProtections, RT_ELEMENTS(s_aProtections));
+}
+
+
+
+static void tstQueryVirtualMemory(void)
+{
+ RTTestISub("NtQueryVirtualMemory");
+
+ uintptr_t cbAdvance = 0;
+ uintptr_t uPtrWhere = 0;
+ for (;;)
+ {
+ SIZE_T cbActual = 0;
+ MEMORY_BASIC_INFORMATION MemInfo = { 0, 0, 0, 0, 0, 0, 0 };
+ NTSTATUS rcNt = NtQueryVirtualMemory(g_hProcess,
+ (void const *)uPtrWhere,
+ MemoryBasicInformation,
+ &MemInfo,
+ sizeof(MemInfo),
+ &cbActual);
+ if (!NT_SUCCESS(rcNt))
+ {
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%p: rcNt=%#x\n", uPtrWhere, rcNt);
+ break;
+ }
+
+ /* stringify the memory state. */
+ char szMemType[1024];
+ char szMemState[1024];
+ char szMemProt[1024];
+ char szAllocProt[1024];
+
+ if ( MemInfo.AllocationBase != NULL
+ && MemInfo.AllocationBase == MemInfo.BaseAddress
+ && MemInfo.Protect != MemInfo.AllocationProtect)
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "\n");
+
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%p-%p %-8s %-8s %-12s",
+ MemInfo.BaseAddress, (uintptr_t)MemInfo.BaseAddress + MemInfo.RegionSize - 1,
+ stringifyMemType(MemInfo.Type, szMemType, sizeof(szMemType)),
+ stringifyMemState(MemInfo.State, szMemState, sizeof(szMemState)),
+ stringifyMemProt(MemInfo.Protect, szMemProt, sizeof(szMemProt))
+ );
+ if ((uintptr_t)MemInfo.AllocationBase != 0)
+ {
+ if (MemInfo.AllocationBase != MemInfo.BaseAddress)
+ RTTestIPrintf(RTTESTLVL_ALWAYS, " %p", MemInfo.AllocationBase);
+ else
+ RTTestIPrintf(RTTESTLVL_ALWAYS, " %s", stringifyMemProt(MemInfo.AllocationProtect, szAllocProt, sizeof(szAllocProt)));
+ }
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "\n");
+
+ if ((uintptr_t)MemInfo.BaseAddress != uPtrWhere)
+ RTTestIPrintf(RTTESTLVL_ALWAYS, " !Warning! Queried %p got BaseAddress=%p!\n",
+ uPtrWhere, MemInfo.BaseAddress);
+
+ /* Image or mapped, then try get a file name. */
+ if (MemInfo.Type == MEM_IMAGE || MemInfo.Type == MEM_MAPPED)
+ {
+ union
+ {
+ MEMORY_SECTION_NAME Core;
+ WCHAR awcPadding[UNICODE_STRING_MAX_CHARS + (sizeof(UNICODE_STRING_MAX_CHARS) + 1) / sizeof(WCHAR)];
+ } uBuf;
+ RT_ZERO(uBuf);
+ uBuf.Core.SectionFileName.Length = UNICODE_STRING_MAX_CHARS * 2;
+ uBuf.Core.SectionFileName.MaximumLength = UNICODE_STRING_MAX_CHARS * 2;
+ uBuf.Core.SectionFileName.Buffer = &uBuf.Core.NameBuffer[0];
+
+ cbActual = 0;
+ rcNt = NtQueryVirtualMemory(g_hProcess,
+ (void const *)uPtrWhere,
+ MemorySectionName,
+ &uBuf,
+ sizeof(uBuf),
+ &cbActual);
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, " %.*ls\n",
+ uBuf.Core.SectionFileName.Length / 2, uBuf.Core.SectionFileName.Buffer);
+ else
+ {
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "%p: MemorySectionName - rcNt=%#x\n", uPtrWhere, rcNt);
+ RTTESTI_CHECK(rcNt == STATUS_FILE_INVALID && MemInfo.Type == MEM_MAPPED);
+ }
+ }
+
+ /* Advance. */
+ cbAdvance = MemInfo.RegionSize;
+ //cbAdvance = 0;
+ if (uPtrWhere + cbAdvance <= uPtrWhere)
+ break;
+ uPtrWhere += MemInfo.RegionSize;
+ }
+}
+
+
+static void tstQueryInformationProcess(void)
+{
+ RTTestISub("NtQueryInformationProcess");
+
+ NTSTATUS rcNt;
+
+ /* Basic info */
+ PROCESS_BASIC_INFORMATION BasicInfo;
+ RT_ZERO(BasicInfo);
+ DWORD cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessBasicInformation,
+ &BasicInfo, sizeof(BasicInfo), &cbActual);
+ RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt));
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "BasicInfo:\n"
+ " UniqueProcessId = %#x (%6d)\n"
+ " PebBaseAddress = %p\n"
+ " Reserved1 = %p ExitStatus?\n"
+ " Reserved2a = %p AffinityMask?\n"
+ " Reserved2b = %p (%6d) BasePriority?\n"
+ " Reserved3 = %p (%6d) InheritedFromUniqueProcessId?\n"
+ ,
+ BasicInfo.UniqueProcessId, BasicInfo.UniqueProcessId,
+ BasicInfo.PebBaseAddress,
+ BasicInfo.Reserved1,
+ BasicInfo.Reserved2[0],
+ BasicInfo.Reserved2[1], BasicInfo.Reserved2[1],
+ BasicInfo.Reserved3, BasicInfo.Reserved3
+ );
+
+
+ /* Debugger present? */
+ DWORD_PTR uPtr = ~(DWORD_PTR)0;
+ cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessDebugPort,
+ &uPtr, sizeof(uPtr), &cbActual);
+ RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt));
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessDebugPort: %p\n", uPtr);
+
+ /* Debug object handle, whatever that is... */
+ uPtr = ~(DWORD_PTR)0;
+ cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessDebugObjectHandle,
+ &uPtr, sizeof(uPtr), &cbActual);
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessDebugObjectHandle: %p\n", uPtr);
+ else if (rcNt == STATUS_PORT_NOT_SET)
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessDebugObjectHandle: rcNt=%#x (STATUS_PORT_NOT_SET)\n", uPtr);
+ else
+ RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt));
+
+ /* 32-bit app on 64-bit host? */
+ uPtr = ~(DWORD_PTR)0;
+ cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessWow64Information,
+ &uPtr, sizeof(uPtr), &cbActual);
+ RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt));
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessWow64Information: %p\n", uPtr);
+
+ /* Process image name (NT). */
+ struct
+ {
+ UNICODE_STRING UniStr;
+ WCHAR awBuffer[UNICODE_STRING_MAX_CHARS];
+ } StrBuf;
+ RT_ZERO(StrBuf);
+ StrBuf.UniStr.Length = UNICODE_STRING_MAX_CHARS * 2;
+ StrBuf.UniStr.MaximumLength = UNICODE_STRING_MAX_CHARS * 2;
+ StrBuf.UniStr.Buffer = &StrBuf.awBuffer[0];
+ cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessImageFileName,
+ &StrBuf, sizeof(StrBuf), &cbActual);
+ RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt));
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileName: len=%u\n %.*ls\n",
+ StrBuf.UniStr.Length, StrBuf.UniStr.Length, StrBuf.UniStr.Buffer);
+
+ /* Process image name (Win32) - Not available on Windows 2003. */
+ RT_ZERO(StrBuf);
+ StrBuf.UniStr.Length = UNICODE_STRING_MAX_CHARS * 2;
+ StrBuf.UniStr.MaximumLength = UNICODE_STRING_MAX_CHARS * 2;
+ StrBuf.UniStr.Buffer = &StrBuf.awBuffer[0];
+ cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessImageFileNameWin32,
+ &StrBuf, sizeof(StrBuf), &cbActual);
+ if (rcNt != STATUS_INVALID_INFO_CLASS)
+ {
+ RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt));
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileNameWin32: len=%u\n %.*ls\n",
+ StrBuf.UniStr.Length, StrBuf.UniStr.Length, StrBuf.UniStr.Buffer);
+ }
+ else
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileNameWin32: Not supported (STATUS_INVALID_INFO_CLASS).\n");
+
+ /* Process image mapping - Not available on Windows 2003. */
+ uPtr = ~(DWORD_PTR)0;
+ cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessImageFileMapping,
+ &uPtr, sizeof(uPtr), &cbActual);
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileMapping: %p\n", uPtr);
+ else if (rcNt == STATUS_OBJECT_TYPE_MISMATCH)
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileMapping: rcNt=%#x (STATUS_OBJECT_TYPE_MISMATCH)\n", rcNt);
+ else if (rcNt == STATUS_INVALID_INFO_CLASS)
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileMapping: Not supported (STATUS_INVALID_INFO_CLASS).\n");
+ else
+ RTTestIFailed("ProcessImageFileMapping: rcNt=%#x\n", rcNt);
+
+
+ /* Handles. Broken for 64-bit input. */
+ uint32_t u32 = UINT32_MAX;
+ cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessHandleCount,
+ &u32, sizeof(u32), &cbActual);
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessHandleCount: %#x (%d)\n", u32, u32);
+ else
+ RTTestIFailed("ProcessHandleCount: rcNt=%#x\n", rcNt);
+
+ /* Execute flags. */
+#if 0 /* fails... wrong process handle? */
+ u32 = ~(DWORD_PTR)0;
+ cbActual = 0;
+ rcNt = NtQueryInformationProcess(g_hProcess,
+ ProcessExecuteFlags,
+ &u32, sizeof(u32), &cbActual);
+ if (NT_SUCCESS(rcNt))
+ RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessExecuteFlags: %#p\n", u32);
+ else
+ RTTestIFailed("ProcessExecuteFlags: rcNt=%#x\n", rcNt);
+#endif
+
+ /** @todo ProcessImageInformation */
+}
+
+
+int main()
+{
+ RTEXITCODE rcExit = RTTestInitAndCreate("tstNtQueryStuff", &g_hTest);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ RTTestBanner(g_hTest);
+
+ g_hProcess = GetCurrentProcess();
+
+ //tstQueryVirtualMemory();
+ tstQueryInformationProcess();
+
+
+ return RTTestSummaryAndDestroy(g_hTest);
+}
+
diff --git a/src/VBox/HostDrivers/Support/testcase/tstPage.cpp b/src/VBox/HostDrivers/Support/testcase/tstPage.cpp
index 26382722..759d86c0 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstPage.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstPage.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2009 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/testcase/tstPin.cpp b/src/VBox/HostDrivers/Support/testcase/tstPin.cpp
index 508ba292..131fa2d9 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstPin.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstPin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp b/src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp
index 0f15f400..a69e9174 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstSupLoadModule.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2009 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -101,11 +101,11 @@ int main(int argc, char **argv)
break;
case 'h':
- RTPrintf("%s [mod1 [mod2...]]\n");
+ RTPrintf("%s [mod1 [mod2...]]\n", argv[0]);
return 1;
case 'V':
- RTPrintf("$Revision: 77327 $\n");
+ RTPrintf("$Revision: 83575 $\n");
return 0;
default:
diff --git a/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp b/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp
index 2b0d2d8f..9358cb05 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp b/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp
index 6f37c63c..bd73c05c 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009-2010 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -287,12 +287,15 @@ int main(int argc, char **argv)
#endif /* !OS2 && !WINDOWS */
{
+
+#define LOOP_COUNT 20
static unsigned const s_acMsIntervals[] = { 0, 1, 2, 3, 4, 8, 10, 16, 32 };
if (RTTestErrorCount(hTest) == 0)
{
RTTestSub(hTest, "SRE Timeout Accuracy (ms)");
RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
+ uint32_t cInterrupted = 0;
for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++)
{
uint64_t cMs = s_acMsIntervals[i];
@@ -300,35 +303,45 @@ int main(int argc, char **argv)
uint64_t cNsMin = UINT64_MAX;
uint64_t cNsTotalSys= 0;
uint64_t cNsTotal = 0;
- for (unsigned j = 0; j < 10; j++)
+ unsigned cLoops = 0;
+ while (cLoops < LOOP_COUNT)
{
uint64_t u64StartSys = RTTimeSystemNanoTS();
uint64_t u64Start = RTTimeNanoTS();
int rcX = SUPSemEventWaitNoResume(pSession, hEvent, cMs);
- if (rcX != VERR_TIMEOUT)
- RTTestFailed(hTest, "%Rrc j=%u cMs=%u", rcX, j, cMs);
uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
uint64_t cNsElapsed = RTTimeNanoTS() - u64Start;
+
+ if (rcX == VERR_INTERRUPTED)
+ {
+ cInterrupted++;
+ continue; /* retry */
+ }
+ if (rcX != VERR_TIMEOUT)
+ RTTestFailed(hTest, "%Rrc cLoops=%u cMs=%u", rcX, cLoops, cMs);
+
if (cNsElapsedSys < cNsMinSys)
cNsMinSys = cNsElapsedSys;
if (cNsElapsed < cNsMin)
cNsMin = cNsElapsed;
cNsTotalSys += cNsElapsedSys;
cNsTotal += cNsElapsed;
+ cLoops++;
}
if (fSys)
{
- RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs);
- RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs);
+ RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs);
+ RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs);
}
if (fGip)
{
- RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs);
- RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%u ms avg (clock=gip)", cMs);
+ RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs);
+ RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=gip)", cMs);
}
}
RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
+ RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned", cInterrupted);
}
if (RTTestErrorCount(hTest) == 0)
@@ -336,6 +349,7 @@ int main(int argc, char **argv)
RTTestSub(hTest, "MRE Timeout Accuracy (ms)");
RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);
+ uint32_t cInterrupted = 0;
for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++)
{
uint64_t cMs = s_acMsIntervals[i];
@@ -343,35 +357,45 @@ int main(int argc, char **argv)
uint64_t cNsMin = UINT64_MAX;
uint64_t cNsTotalSys= 0;
uint64_t cNsTotal = 0;
- for (unsigned j = 0; j < 10; j++)
+ unsigned cLoops = 0;
+ while (cLoops < LOOP_COUNT)
{
uint64_t u64StartSys = RTTimeSystemNanoTS();
uint64_t u64Start = RTTimeNanoTS();
int rcX = SUPSemEventMultiWaitNoResume(pSession, hEvent, cMs);
- if (rcX != VERR_TIMEOUT)
- RTTestFailed(hTest, "%Rrc j=%u cMs=%u", rcX, j, cMs);
uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
uint64_t cNsElapsed = RTTimeNanoTS() - u64Start;
+
+ if (rcX == VERR_INTERRUPTED)
+ {
+ cInterrupted++;
+ continue; /* retry */
+ }
+ if (rcX != VERR_TIMEOUT)
+ RTTestFailed(hTest, "%Rrc cLoops=%u cMs=%u", rcX, cLoops, cMs);
+
if (cNsElapsedSys < cNsMinSys)
cNsMinSys = cNsElapsedSys;
if (cNsElapsed < cNsMin)
cNsMin = cNsElapsed;
cNsTotalSys += cNsElapsedSys;
cNsTotal += cNsElapsed;
+ cLoops++;
}
if (fSys)
{
- RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs);
- RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs);
+ RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs);
+ RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs);
}
if (fGip)
{
- RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs);
- RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%u ms avg (clock=gip)", cMs);
+ RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs);
+ RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=gip)", cMs);
}
}
RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
+ RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned", cInterrupted);
}
}
@@ -387,6 +411,7 @@ int main(int argc, char **argv)
RTTestValueF(hTest, SUPSemEventGetResolution(pSession), RTTESTUNIT_NS, "SRE resolution");
RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
+ uint32_t cInterrupted = 0;
for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
{
uint64_t cNs = s_acNsIntervals[i];
@@ -394,35 +419,45 @@ int main(int argc, char **argv)
uint64_t cNsMin = UINT64_MAX;
uint64_t cNsTotalSys= 0;
uint64_t cNsTotal = 0;
- for (unsigned j = 0; j < 10; j++)
+ unsigned cLoops = 0;
+ while (cLoops < LOOP_COUNT)
{
uint64_t u64StartSys = RTTimeSystemNanoTS();
uint64_t u64Start = RTTimeNanoTS();
int rcX = SUPSemEventWaitNsRelIntr(pSession, hEvent, cNs);
- if (rcX != VERR_TIMEOUT)
- RTTestFailed(hTest, "%Rrc j=%u cNs=%u", rcX, j, cNs);
uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
uint64_t cNsElapsed = RTTimeNanoTS() - u64Start;
+
+ if (rcX == VERR_INTERRUPTED)
+ {
+ cInterrupted++;
+ continue; /* retry */
+ }
+ if (rcX != VERR_TIMEOUT)
+ RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs);
+
if (cNsElapsedSys < cNsMinSys)
cNsMinSys = cNsElapsedSys;
if (cNsElapsed < cNsMin)
cNsMin = cNsElapsed;
cNsTotalSys += cNsElapsedSys;
cNsTotal += cNsElapsed;
+ cLoops++;
}
if (fSys)
{
- RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs);
- RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
+ RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs);
+ RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
}
if (fGip)
{
- RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs);
- RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs);
+ RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs);
+ RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs);
}
}
RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
+ RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned", cInterrupted);
}
if (RTTestErrorCount(hTest) == 0)
@@ -431,6 +466,7 @@ int main(int argc, char **argv)
RTTestValueF(hTest, SUPSemEventMultiGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);
+ uint32_t cInterrupted = 0;
for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
{
uint64_t cNs = s_acNsIntervals[i];
@@ -438,35 +474,45 @@ int main(int argc, char **argv)
uint64_t cNsMin = UINT64_MAX;
uint64_t cNsTotalSys= 0;
uint64_t cNsTotal = 0;
- for (unsigned j = 0; j < 10; j++)
+ unsigned cLoops = 0;
+ while (cLoops < LOOP_COUNT)
{
uint64_t u64StartSys = RTTimeSystemNanoTS();
uint64_t u64Start = RTTimeNanoTS();
int rcX = SUPSemEventMultiWaitNsRelIntr(pSession, hEvent, cNs);
- if (rcX != VERR_TIMEOUT)
- RTTestFailed(hTest, "%Rrc j=%u cNs=%u", rcX, j, cNs);
uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
uint64_t cNsElapsed = RTTimeNanoTS() - u64Start;
+
+ if (rcX == VERR_INTERRUPTED)
+ {
+ cInterrupted++;
+ continue; /* retry */
+ }
+ if (rcX != VERR_TIMEOUT)
+ RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs);
+
if (cNsElapsedSys < cNsMinSys)
cNsMinSys = cNsElapsedSys;
if (cNsElapsed < cNsMin)
cNsMin = cNsElapsed;
cNsTotalSys += cNsElapsedSys;
cNsTotal += cNsElapsed;
+ cLoops++;
}
if (fSys)
{
- RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs);
- RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
+ RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs);
+ RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
}
if (fGip)
{
- RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs);
- RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs);
+ RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs);
+ RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs);
}
}
RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
+ RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned", cInterrupted);
}
if (RTTestErrorCount(hTest) == 0)
@@ -475,6 +521,7 @@ int main(int argc, char **argv)
RTTestValueF(hTest, SUPSemEventGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
+ uint32_t cInterrupted = 0;
for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
{
uint64_t cNs = s_acNsIntervals[i];
@@ -482,36 +529,46 @@ int main(int argc, char **argv)
uint64_t cNsMin = UINT64_MAX;
uint64_t cNsTotalSys= 0;
uint64_t cNsTotal = 0;
- for (unsigned j = 0; j < 10; j++)
+ unsigned cLoops = 0;
+ while (cLoops < LOOP_COUNT)
{
uint64_t u64StartSys = RTTimeSystemNanoTS();
uint64_t u64Start = RTTimeNanoTS();
uint64_t uAbsDeadline = (fGip ? u64Start : u64StartSys) + cNs;
int rcX = SUPSemEventWaitNsAbsIntr(pSession, hEvent, uAbsDeadline);
- if (rcX != VERR_TIMEOUT)
- RTTestFailed(hTest, "%Rrc j=%u cNs=%u", rcX, j, cNs);
uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
uint64_t cNsElapsed = RTTimeNanoTS() - u64Start;
+
+ if (rcX == VERR_INTERRUPTED)
+ {
+ cInterrupted++;
+ continue; /* retry */
+ }
+ if (rcX != VERR_TIMEOUT)
+ RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs);
+
if (cNsElapsedSys < cNsMinSys)
cNsMinSys = cNsElapsedSys;
if (cNsElapsed < cNsMin)
cNsMin = cNsElapsed;
cNsTotalSys += cNsElapsedSys;
cNsTotal += cNsElapsed;
+ cLoops++;
}
if (fSys)
{
- RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs);
- RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
+ RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs);
+ RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
}
if (fGip)
{
- RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs);
- RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs);
+ RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs);
+ RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs);
}
}
RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
+ RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned", cInterrupted);
}
@@ -521,6 +578,7 @@ int main(int argc, char **argv)
RTTestValueF(hTest, SUPSemEventMultiGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);
+ uint32_t cInterrupted = 0;
for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
{
uint64_t cNs = s_acNsIntervals[i];
@@ -528,36 +586,46 @@ int main(int argc, char **argv)
uint64_t cNsMin = UINT64_MAX;
uint64_t cNsTotalSys= 0;
uint64_t cNsTotal = 0;
- for (unsigned j = 0; j < 10; j++)
+ unsigned cLoops = 0;
+ while (cLoops < LOOP_COUNT)
{
uint64_t u64StartSys = RTTimeSystemNanoTS();
uint64_t u64Start = RTTimeNanoTS();
uint64_t uAbsDeadline = (fGip ? u64Start : u64StartSys) + cNs;
int rcX = SUPSemEventMultiWaitNsAbsIntr(pSession, hEvent, uAbsDeadline);
- if (rcX != VERR_TIMEOUT)
- RTTestFailed(hTest, "%Rrc j=%u cNs=%u", rcX, j, cNs);
uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
uint64_t cNsElapsed = RTTimeNanoTS() - u64Start;
+
+ if (rcX == VERR_INTERRUPTED)
+ {
+ cInterrupted++;
+ continue; /* retry */
+ }
+ if (rcX != VERR_TIMEOUT)
+ RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs);
+
if (cNsElapsedSys < cNsMinSys)
cNsMinSys = cNsElapsedSys;
if (cNsElapsed < cNsMin)
cNsMin = cNsElapsed;
cNsTotalSys += cNsElapsedSys;
cNsTotal += cNsElapsed;
+ cLoops++;
}
if (fSys)
{
- RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs);
- RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
+ RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs);
+ RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
}
if (fGip)
{
- RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs);
- RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs);
+ RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs);
+ RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs);
}
}
RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
+ RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned", cInterrupted);
}
}
diff --git a/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp b/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
index 65ce0b31..a3cafc6d 100644
--- a/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -46,15 +46,23 @@
*******************************************************************************/
/** The support service name. */
#define SERVICE_NAME "VBoxDrv"
-/** Win32 Device name. */
-#define DEVICE_NAME "\\\\.\\VBoxDrv"
-/** NT Device name. */
-#define DEVICE_NAME_NT L"\\Device\\VBoxDrv"
-/** Win Symlink name. */
-#define DEVICE_NAME_DOS L"\\DosDevices\\VBoxDrv"
/** The Pool tag (VBox). */
#define SUPDRV_NT_POOL_TAG 'xoBV'
+/** Win32 device name for system access. */
+#define DEVICE_NAME_SYS "\\\\.\\VBoxDrv"
+/** NT device name for system access. */
+#define DEVICE_NAME_NT_SYS L"\\Device\\VBoxDrv"
+/** Win Symlink name for system access. */
+#define DEVICE_NAME_DOS_SYS L"\\DosDevices\\VBoxDrv"
+
+/** Win32 device name for user access. */
+#define DEVICE_NAME_USR "\\\\.\\VBoxDrvU"
+/** NT device name for user access. */
+#define DEVICE_NAME_NT_USR L"\\Device\\VBoxDrvU"
+/** Win Symlink name for user access. */
+#define DEVICE_NAME_DOS_USR L"\\DosDevices\\VBoxDrvU"
+
/*******************************************************************************
* Structures and Typedefs *
@@ -68,6 +76,28 @@ typedef struct SUPDRVEXECMEM
} SUPDRVEXECMEM, *PSUPDRVEXECMEM;
#endif
+/**
+ * Device extension used by VBoxDrvU.
+ */
+typedef struct SUPDRVDEVEXTUSR
+{
+ /** Global cookie (same location as in SUPDRVDEVEXT, different value). */
+ uint32_t u32Cookie;
+ /** Pointer to the main driver extension. */
+ PSUPDRVDEVEXT pMainDrvExt;
+} SUPDRVDEVEXTUSR;
+AssertCompileMembersAtSameOffset(SUPDRVDEVEXT, u32Cookie, SUPDRVDEVEXTUSR, u32Cookie);
+/** Pointer to the VBoxDrvU device extension. */
+typedef SUPDRVDEVEXTUSR *PSUPDRVDEVEXTUSR;
+/** Value of SUPDRVDEVEXTUSR::u32Cookie. */
+#define SUPDRVDEVEXTUSR_COOKIE UINT32_C(0x12345678)
+
+/** Get the main device extension. */
+#define SUPDRVNT_GET_DEVEXT(pDevObj) \
+ ( pDevObj != g_pDevObjUsr \
+ ? (PSUPDRVDEVEXT)pDevObj->DeviceExtension \
+ : ((PSUPDRVDEVEXTUSR)pDevObj->DeviceExtension)->pMainDrvExt )
+
/*******************************************************************************
* Internal Functions *
@@ -92,6 +122,90 @@ ULONG _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
RT_C_DECLS_END
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** Pointer to the system device instance. */
+static PDEVICE_OBJECT g_pDevObjSys = NULL;
+/** Pointer to the user device instance. */
+static PDEVICE_OBJECT g_pDevObjUsr = NULL;
+
+
+/**
+ * Takes care of creating the devices and their symbolic links.
+ *
+ * @returns NT status code.
+ * @param pDrvObj Pointer to driver object.
+ */
+static NTSTATUS vboxdrvNtCreateDevices(PDRIVER_OBJECT pDrvObj)
+{
+ /*
+ * System device.
+ */
+ UNICODE_STRING DevName;
+ RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_SYS);
+ NTSTATUS rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXT), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjSys);
+ if (NT_SUCCESS(rcNt))
+ {
+ UNICODE_STRING DosName;
+ RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS_SYS);
+ rcNt = IoCreateSymbolicLink(&DosName, &DevName);
+ if (NT_SUCCESS(rcNt))
+ {
+ /*
+ * User device.
+ */
+ RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_USR);
+ rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTUSR), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjUsr);
+ if (NT_SUCCESS(rcNt))
+ {
+ UNICODE_STRING DosName;
+ RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS_USR);
+ rcNt = IoCreateSymbolicLink(&DosName, &DevName);
+ if (NT_SUCCESS(rcNt))
+ {
+ PSUPDRVDEVEXTUSR pDevExtUsr = (PSUPDRVDEVEXTUSR)g_pDevObjUsr->DeviceExtension;
+ pDevExtUsr->pMainDrvExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
+ pDevExtUsr->u32Cookie = SUPDRVDEVEXTUSR_COOKIE;
+
+ /* Done. */
+ return rcNt;
+ }
+
+ /* Bail out. */
+ IoDeleteDevice(g_pDevObjUsr);
+ g_pDevObjUsr = NULL;
+ }
+ IoDeleteSymbolicLink(&DosName);
+ }
+ IoDeleteDevice(g_pDevObjSys);
+ g_pDevObjSys = NULL;
+ }
+ return rcNt;
+}
+
+/**
+ * Destroys the devices and links created by vboxdrvNtCreateDevices.
+ */
+static void vboxdrvNtDestroyDevices(void)
+{
+ UNICODE_STRING DosName;
+ RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS_SYS);
+ NTSTATUS rcNt = IoDeleteSymbolicLink(&DosName);
+
+ RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS_USR);
+ rcNt = IoDeleteSymbolicLink(&DosName);
+
+ PSUPDRVDEVEXTUSR pDevExtUsr = (PSUPDRVDEVEXTUSR)g_pDevObjUsr->DeviceExtension;
+ pDevExtUsr->pMainDrvExt = NULL;
+
+ IoDeleteDevice(g_pDevObjUsr);
+ g_pDevObjUsr = NULL;
+ IoDeleteDevice(g_pDevObjSys);
+ g_pDevObjSys = NULL;
+}
+
+
/**
* Driver entry point.
*
@@ -101,91 +215,74 @@ RT_C_DECLS_END
*/
ULONG _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
- NTSTATUS rc;
-
/*
* Create device.
* (That means creating a device object and a symbolic link so the DOS
* subsystems (OS/2, win32, ++) can access the device.)
*/
- UNICODE_STRING DevName;
- RtlInitUnicodeString(&DevName, DEVICE_NAME_NT);
- PDEVICE_OBJECT pDevObj;
- rc = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXT), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);
- if (NT_SUCCESS(rc))
+ NTSTATUS rcNt = vboxdrvNtCreateDevices(pDrvObj);
+ if (NT_SUCCESS(rcNt))
{
- UNICODE_STRING DosName;
- RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS);
- rc = IoCreateSymbolicLink(&DosName, &DevName);
- if (NT_SUCCESS(rc))
+ int vrc = RTR0Init(0);
+ if (RT_SUCCESS(vrc))
{
- int vrc = RTR0Init(0);
- if (RT_SUCCESS(vrc))
- {
- Log(("VBoxDrv::DriverEntry\n"));
+ Log(("VBoxDrv::DriverEntry\n"));
+
+ /*
+ * Initialize the device extension.
+ */
+ PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
+ memset(pDevExt, 0, sizeof(*pDevExt));
+ vrc = supdrvInitDevExt(pDevExt, sizeof(SUPDRVSESSION));
+ if (!vrc)
+ {
/*
- * Initialize the device extension.
+ * Setup the driver entry points in pDrvObj.
*/
- PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDevObj->DeviceExtension;
- memset(pDevExt, 0, sizeof(*pDevExt));
-
- vrc = supdrvInitDevExt(pDevExt, sizeof(SUPDRVSESSION));
- if (!vrc)
- {
- /*
- * Setup the driver entry points in pDrvObj.
- */
- pDrvObj->DriverUnload = VBoxDrvNtUnload;
- pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxDrvNtCreate;
- pDrvObj->MajorFunction[IRP_MJ_CLEANUP] = VBoxDrvNtCleanup;
- pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxDrvNtClose;
- pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxDrvNtDeviceControl;
- pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxDrvNtInternalDeviceControl;
- pDrvObj->MajorFunction[IRP_MJ_READ] = VBoxDrvNtNotSupportedStub;
- pDrvObj->MajorFunction[IRP_MJ_WRITE] = VBoxDrvNtNotSupportedStub;
-
- /* more? */
-
- /* Register ourselves for power state changes. */
- UNICODE_STRING CallbackName;
- OBJECT_ATTRIBUTES Attr;
-
- RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState");
- InitializeObjectAttributes(&Attr, &CallbackName, OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- rc = ExCreateCallback(&pDevExt->pObjPowerCallback, &Attr, TRUE, TRUE);
- if (rc == STATUS_SUCCESS)
- pDevExt->hPowerCallback = ExRegisterCallback(pDevExt->pObjPowerCallback, VBoxPowerDispatchCallback, pDevObj);
-
- Log(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n"));
- return STATUS_SUCCESS;
- }
+ pDrvObj->DriverUnload = VBoxDrvNtUnload;
+ pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxDrvNtCreate;
+ pDrvObj->MajorFunction[IRP_MJ_CLEANUP] = VBoxDrvNtCleanup;
+ pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxDrvNtClose;
+ pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxDrvNtDeviceControl;
+ pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxDrvNtInternalDeviceControl;
+ pDrvObj->MajorFunction[IRP_MJ_READ] = VBoxDrvNtNotSupportedStub;
+ pDrvObj->MajorFunction[IRP_MJ_WRITE] = VBoxDrvNtNotSupportedStub;
+
+ /* more? */
+
+ /* Register ourselves for power state changes. */
+ UNICODE_STRING CallbackName;
+ OBJECT_ATTRIBUTES Attr;
+
+ RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState");
+ InitializeObjectAttributes(&Attr, &CallbackName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ rcNt = ExCreateCallback(&pDevExt->pObjPowerCallback, &Attr, TRUE, TRUE);
+ if (rcNt == STATUS_SUCCESS)
+ pDevExt->hPowerCallback = ExRegisterCallback(pDevExt->pObjPowerCallback, VBoxPowerDispatchCallback,
+ g_pDevObjSys);
+
+ Log(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n"));
+ return STATUS_SUCCESS;
+ }
- Log(("supdrvInitDevExit failed with vrc=%d!\n", vrc));
- rc = VBoxDrvNtErr2NtStatus(vrc);
+ Log(("supdrvInitDevExit failed with vrc=%d!\n", vrc));
+ rcNt = VBoxDrvNtErr2NtStatus(vrc);
- IoDeleteSymbolicLink(&DosName);
- RTR0Term();
- }
- else
- {
- Log(("RTR0Init failed with vrc=%d!\n", vrc));
- rc = VBoxDrvNtErr2NtStatus(vrc);
- }
+ RTR0Term();
}
else
- Log(("IoCreateSymbolicLink failed with rc=%#x!\n", rc));
+ {
+ Log(("RTR0Init failed with vrc=%d!\n", vrc));
+ rcNt = VBoxDrvNtErr2NtStatus(vrc);
+ }
- IoDeleteDevice(pDevObj);
+ vboxdrvNtDestroyDevices();
}
- else
- Log(("IoCreateDevice failed with rc=%#x!\n", rc));
-
- if (NT_SUCCESS(rc))
- rc = STATUS_INVALID_PARAMETER;
- Log(("VBoxDrv::DriverEntry returning %#x\n", rc));
- return rc;
+ if (NT_SUCCESS(rcNt))
+ rcNt = STATUS_INVALID_PARAMETER;
+ return rcNt;
}
@@ -196,7 +293,7 @@ ULONG _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
*/
void _stdcall VBoxDrvNtUnload(PDRIVER_OBJECT pDrvObj)
{
- PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDrvObj->DeviceObject->DeviceExtension;
+ PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
Log(("VBoxDrvNtUnload at irql %d\n", KeGetCurrentIrql()));
@@ -208,18 +305,12 @@ void _stdcall VBoxDrvNtUnload(PDRIVER_OBJECT pDrvObj)
/*
* We ASSUME that it's not possible to unload a driver with open handles.
- * Start by deleting the symbolic link
- */
- UNICODE_STRING DosName;
- RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS);
- NTSTATUS rc = IoDeleteSymbolicLink(&DosName);
-
- /*
- * Terminate the GIP page and delete the device extension.
*/
supdrvDeleteDevExt(pDevExt);
RTR0Term();
- IoDeleteDevice(pDrvObj->DeviceObject);
+ vboxdrvNtDestroyDevices();
+
+ NOREF(pDrvObj);
}
@@ -232,9 +323,10 @@ void _stdcall VBoxDrvNtUnload(PDRIVER_OBJECT pDrvObj)
NTSTATUS _stdcall VBoxDrvNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
Log(("VBoxDrvNtCreate: RequestorMode=%d\n", pIrp->RequestorMode));
+ const bool fUnrestricted = pDevObj == g_pDevObjSys;
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
PFILE_OBJECT pFileObj = pStack->FileObject;
- PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDevObj->DeviceExtension;
+ PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
/*
* We are not remotely similar to a directory...
@@ -264,7 +356,7 @@ NTSTATUS _stdcall VBoxDrvNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
*/
pFileObj->FsContext = NULL;
PSUPDRVSESSION pSession;
- int rc = supdrvCreateSession(pDevExt, true /*fUser*/, &pSession);
+ int rc = supdrvCreateSession(pDevExt, true /*fUser*/, fUnrestricted, &pSession);
if (!rc)
pFileObj->FsContext = pSession;
rcNt = pIrp->IoStatus.Status = VBoxDrvNtErr2NtStatus(rc);
@@ -285,7 +377,7 @@ NTSTATUS _stdcall VBoxDrvNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
*/
NTSTATUS _stdcall VBoxDrvNtCleanup(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDevObj->DeviceExtension;
+ PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
PFILE_OBJECT pFileObj = pStack->FileObject;
PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFileObj->FsContext;
@@ -293,7 +385,7 @@ NTSTATUS _stdcall VBoxDrvNtCleanup(PDEVICE_OBJECT pDevObj, PIRP pIrp)
Log(("VBoxDrvNtCleanup: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pSession));
if (pSession)
{
- supdrvCloseSession(pDevExt, (PSUPDRVSESSION)pFileObj->FsContext);
+ supdrvSessionRelease(pSession);
pFileObj->FsContext = NULL;
}
@@ -313,7 +405,7 @@ NTSTATUS _stdcall VBoxDrvNtCleanup(PDEVICE_OBJECT pDevObj, PIRP pIrp)
*/
NTSTATUS _stdcall VBoxDrvNtClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDevObj->DeviceExtension;
+ PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
PFILE_OBJECT pFileObj = pStack->FileObject;
PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFileObj->FsContext;
@@ -321,7 +413,7 @@ NTSTATUS _stdcall VBoxDrvNtClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
Log(("VBoxDrvNtClose: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pSession));
if (pSession)
{
- supdrvCloseSession(pDevExt, (PSUPDRVSESSION)pFileObj->FsContext);
+ supdrvSessionRelease(pSession);
pFileObj->FsContext = NULL;
}
@@ -341,8 +433,8 @@ NTSTATUS _stdcall VBoxDrvNtClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
*/
NTSTATUS _stdcall VBoxDrvNtDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDevObj->DeviceExtension;
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
PSUPDRVSESSION pSession = (PSUPDRVSESSION)pStack->FileObject->FsContext;
/*
@@ -354,13 +446,14 @@ NTSTATUS _stdcall VBoxDrvNtDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* interface.
*/
ULONG ulCmd = pStack->Parameters.DeviceIoControl.IoControlCode;
- if ( ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN
- || ulCmd == SUP_IOCTL_FAST_DO_HWACC_RUN
- || ulCmd == SUP_IOCTL_FAST_DO_NOP)
+ if ( ( ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN
+ || ulCmd == SUP_IOCTL_FAST_DO_HM_RUN
+ || ulCmd == SUP_IOCTL_FAST_DO_NOP)
+ && pSession->fUnrestricted == true)
{
-#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
int rc = supdrvIOCtlFast(ulCmd, (unsigned)(uintptr_t)pIrp->UserBuffer /* VMCPU id */, pDevExt, pSession);
-#else
+
+#if 0 /* When preemption was not used i.e. !VBOX_WITH_VMMR0_DISABLE_PREEMPTION. That's no longer required. */
/* Raise the IRQL to DISPATCH_LEVEL to prevent Windows from rescheduling us to another CPU/core. */
Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
KIRQL oldIrql;
@@ -474,8 +567,8 @@ static int VBoxDrvNtDeviceControlSlow(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSes
*/
NTSTATUS _stdcall VBoxDrvNtInternalDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDevObj->DeviceExtension;
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
PFILE_OBJECT pFileObj = pStack ? pStack->FileObject : NULL;
PSUPDRVSESSION pSession = pFileObj ? (PSUPDRVSESSION)pFileObj->FsContext : NULL;
NTSTATUS rcNt;
@@ -565,7 +658,7 @@ NTSTATUS _stdcall VBoxDrvNtInternalDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pI
NTSTATUS _stdcall VBoxDrvNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
Log(("VBoxDrvNtNotSupportedStub\n"));
- pDevObj = pDevObj;
+ NOREF(pDevObj);
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
diff --git a/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm b/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm
index f7d5e953..11fdcf38 100644
--- a/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm
+++ b/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm
@@ -4,7 +4,7 @@
;
;
-; Copyright (C) 2006-2009 Oracle Corporation
+; Copyright (C) 2006-2010 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp b/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp
index d12ea3c3..99e5e789 100644
--- a/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -56,8 +56,10 @@
*******************************************************************************/
/** The support service name. */
#define SERVICE_NAME "VBoxDrv"
-/** Win32 Device name. */
-#define DEVICE_NAME "\\\\.\\VBoxDrv"
+/** Win32 Device name - system. */
+#define DEVICE_NAME_SYS "\\\\.\\VBoxDrv"
+/** Win32 Device name - user. */
+#define DEVICE_NAME_USR "\\\\.\\VBoxDrvU"
/** NT Device name. */
#define DEVICE_NAME_NT L"\\Device\\VBoxDrv"
/** Win32 Symlink name. */
@@ -77,7 +79,7 @@ static int suplibConvertWin32Err(int);
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
{
/*
* Nothing to do if pre-inited.
@@ -88,7 +90,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* Try open the device.
*/
- HANDLE hDevice = CreateFile(DEVICE_NAME,
+ HANDLE hDevice = CreateFile(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
@@ -102,7 +104,7 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
*/
suplibOsStartService();
- hDevice = CreateFile(DEVICE_NAME,
+ hDevice = CreateFile(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
@@ -138,7 +140,8 @@ int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
/*
* We're done.
*/
- pThis->hDevice = hDevice;
+ pThis->hDevice = hDevice;
+ pThis->fUnrestricted = fUnrestricted;
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c b/src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c
index 536982d5..16099838 100644
--- a/src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c
+++ b/src/VBox/HostDrivers/Support/win/SUPR0IdcClient-win.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp b/src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp
index 1682f5ce..435226b2 100644
--- a/src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPSvc-win.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/HostDrivers/Support/win/VBoxDrv.inf b/src/VBox/HostDrivers/Support/win/VBoxDrv.inf
index 4a5b8661..b7ad3e91 100644
--- a/src/VBox/HostDrivers/Support/win/VBoxDrv.inf
+++ b/src/VBox/HostDrivers/Support/win/VBoxDrv.inf
@@ -4,7 +4,7 @@
;
;
-; Copyright (C) 2006-2007 Oracle Corporation
+; Copyright (C) 2006-2010 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;