diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
---|---|---|
committer | <> | 2014-05-08 15:03:54 +0000 |
commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/HostDrivers/Support | |
parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
download | VirtualBox-master.tar.gz |
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/HostDrivers/Support')
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;
|