VMMR0.cpp revision 1d2d38b5af44dca06849ba586f29753c3c982072
77b1a2d8b5dbe2c0b5200794914239fee3c8ee5dvboxsync * VMM - Host Context Ring 0.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * available from http://www.virtualbox.org. This file is free software;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Header Files *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#if defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Internal Functions *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Global Variables *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** Pointer to the internal networking service instance. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Initialize the module.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * This is called when we're first loaded.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @returns 0 on success.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @returns VBox status on failure.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Initialize the GVMM, GMM.& HWACCM
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("ModuleInit: g_pIntNet=%p\n", g_pIntNet));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("ModuleInit: g_pIntNet=%p should be NULL now...\n", g_pIntNet));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("ModuleInit: returns success. g_pIntNet=%p\n", g_pIntNet));
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Terminate the module.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * This is called when we're finally unloaded.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Destroy the internal networking instance.
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* Global HWACCM cleanup */
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Destroy the GMM and GVMM instances.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Initaties the R0 driver for a particular VM instance.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * @returns VBox status code.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pVM The VM instance in question.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @param uSvnRev The SVN revision of the ring-3 part.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @thread EMT.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Match the SVN revisions.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Register the EMT R0 logger instance.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#if 0 /* testing of the logger. */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: before %p\n", RTLogDefaultInstance()));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: pfnFlush=%p actual=%p\n", pR0Logger->Logger.pfnFlush, vmmR0LoggerFlush));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: pfnLogger=%p actual=%p\n", pR0Logger->Logger.pfnLogger, vmmR0LoggerWrapper));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: offScratch=%d fFlags=%#x fDestFlags=%#x\n", pR0Logger->Logger.offScratch, pR0Logger->Logger.fFlags, pR0Logger->Logger.fDestFlags));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: after %p reg\n", RTLogDefaultInstance()));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: after %p dereg\n", RTLogDefaultInstance()));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: returned succesfully from direct logger call.\n"));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogCom(("VMMR0Init: returned succesfully from direct flush call.\n"));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogCom(("VMMR0Init: after %p reg2\n", RTLogDefaultInstance()));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogCom(("VMMR0Init: returned succesfully from direct logger call (2). offScratch=%d\n", pR0Logger->Logger.offScratch));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogCom(("VMMR0Init: after %p dereg2\n", RTLogDefaultInstance()));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync RTLogLoggerEx(&pR0Logger->Logger, 0, ~0U, "hello ring-0 logger (RTLogLoggerEx)\n");
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogCom(("VMMR0Init: RTLogLoggerEx returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync RTLogPrintf("hello ring-0 logger (RTLogPrintf)\n");
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogCom(("VMMR0Init: RTLogPrintf returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync Log(("Switching to per-thread logging instance %p (key=%p)\n", &pR0Logger->Logger, pVM->pSession));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Initialize the per VM data for GVMM and GMM.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync// if (RT_SUCCESS(rc))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync// rc = GMMR0InitPerVMData(pVM);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Init HWACCM.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Init CPUM.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* failed */
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync * Terminates the R0 driver for a particular VM instance.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * @returns VBox status code.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param pVM The VM instance in question.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * @thread EMT.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Deregister the logger.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * Calls the ring-3 host code.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * @returns VBox status code of the ring-3 call.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * @param pVM The VM handle.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * @param enmOperation The operation.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * @param uArg The argument to the operation.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsyncVMMR0DECL(int) VMMR0CallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg)
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** @todo profile this! */
9496f2d398b49813176939d7a339ae513d5175efvboxsync int rc = vmmR0CallHostLongJmp(&pVM->vmm.s.CallHostR0JmpBuf, VINF_VMM_CALL_HOST);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Record return code statistics
ffbe6daf773e38167f3cabaf1f063d84ecd063e9vboxsync * @param pVM The VM handle.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param rc The status code.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Collect statistics.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterruptHyper);
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRingSwitchInt);
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetExceptionPrivilege);
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetStaleSelector);
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOReadWrite);
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOPatchRead);
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOPatchWrite);
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchEmulate);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchIretIRQ);
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPageOverflow);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRescheduleREM);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetTimerPending);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterruptPending);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDMQueueFlush);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMPoolGrow);
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetVMSetRuntimeError);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetHyperAssertion);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPATMDuplicateFn);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMChangeMode);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPendingRequest);
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync#endif /* VBOX_WITH_STATISTICS */
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * The Ring 0 entry point, called by the interrupt gate.
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync * @returns VBox status code.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * @param pVM The VM to operate on.
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync * @param enmOperation Which operation to execute.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * @param pvArg Argument to the operation.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * @remarks Assume called with interrupts disabled.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsyncVMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg)
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync * Switch to GC.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * These calls return whatever the GC returns.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Safety precaution as VMX disables the switcher. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync register int rc;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pVM->vmm.s.iLastGCRc = rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * We'll let TRPM change the stack frame so our return is different.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Just keep in mind that after the call, things have changed!
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Don't trust the compiler to get this right.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * gcc -fomit-frame-pointer screws up big time here. This works fine in 64-bit
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * mode too because we push the arguments on the stack in the IDT patch code.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync# if defined(__GNUC__)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync void *pvRet = (uint8_t *)__builtin_frame_address(0) + sizeof(void *);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync# elif defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync void *pvRet = (uint8_t *)_AddressOfReturnAddress();
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync && ((uintptr_t *)pvRet)[2] == (uintptr_t)enmOperation
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync static bool s_fHaveWarned = false;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync RTLogPrintf("VMMR0.r0: The compiler can't find the stack frame!\n");
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync RTLogComPrintf("VMMR0.r0: The compiler can't find the stack frame!\n");
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Switch to GC to execute Hypervisor function.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Safety precaution as VMX disables the switcher. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /** @todo dispatch interrupts? */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * For profiling.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#endif /* VBOX_WITH_IDT_PATCHING */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * We're returning VERR_NOT_SUPPORT here so we've got something else
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * than -1 which the interrupt gate glue code might return.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Log(("operation %#x is not supported\n", enmOperation));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * The Ring 0 entry point, called by the fast-ioctl path.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param pVM The VM to operate on.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * The return code is stored in pVM->vmm.s.iLastGCRc.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param enmOperation Which operation to execute.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @remarks Assume called with interrupts _enabled_.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncVMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMMR0OPERATION enmOperation)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Switch to GC and run guest raw mode code.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Disable interrupts before doing the world switch.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Safety precaution as hwaccm disables the switcher. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Run guest code using the available hardware acceleration technology.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Disable interrupts before we do anything interesting. On Windows we avoid
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * this by having the support driver raise the IRQL before calling us, this way
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * we hope to get away we page faults and later calling into the kernel.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#ifndef RT_OS_WINDOWS /** @todo check other hosts */
efff36b306e370346025647a158689021df2e1d1vboxsync rc = vmmR0CallHostSetJmp(&pVM->vmm.s.CallHostR0JmpBuf, HWACCMR0RunGuestCode, pVM); /* this may resume code. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#ifndef RT_OS_WINDOWS /** @todo check other hosts */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* No special action required for external interrupts, just return. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * For profiling.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * Impossible.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Validates a session or VM session argument.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @returns true / false accordingly.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param pVM The VM argument.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pSession The session argument.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsyncDECLINLINE(bool) vmmR0IsValidSession(PVM pVM, PSUPDRVSESSION pClaimedSession, PSUPDRVSESSION pSession)
fe813b3594039ba864493438e78ee0e7132bc445vboxsync /* This must be set! */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return false;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Only one out of the two. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return false;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * VMMR0EntryEx worker function, either called directly or when ever possible
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * called thru a longjmp so we can exit safely on failure.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @returns VBox status code.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @param pVM The VM to operate on.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @param enmOperation Which operation to execute.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pReqHdr This points to a SUPVMMR0REQHDR packet. Optional.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * The support driver validates this if it's present.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param u64Arg Some simple constant argument.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pSession The session of the caller.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @remarks Assume called with interrupts _enabled_.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsyncstatic int vmmR0EntryExWorker(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Common VM pointer validation.
fe813b3594039ba864493438e78ee0e7132bc445vboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p! (op=%d)\n", pVM, enmOperation);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (RT_UNLIKELY( pVM->enmVMState < VMSTATE_CREATING
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p:{enmVMState=%d, .pVMR0=%p}! (op=%d)\n",
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * GVM requests
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr);
fe813b3594039ba864493438e78ee0e7132bc445vboxsync return GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr);
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Initialize the R0 part of a VM instance.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Terminate the R0 part of a VM instance.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Attempt to enable hwacc mode and check the current setting.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return HWACCMR0EnableAllCpus(pVM, (HWACCMSTATE)u64Arg);
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Setup the hardware accelerated raw-mode session.
fe813b3594039ba864493438e78ee0e7132bc445vboxsync * Switch to GC to execute Hypervisor function.
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* Safety precaution as HWACCM can disable the switcher. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** @todo dispatch interrupts? */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * PGM wrappers.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * GMM wrappers.
da3503c04ce76e653401396fe2795a9bc2427a1dvboxsync return GMMR0InitialReservationReq(pVM, (PGMMINITIALRESERVATIONREQ)pReqHdr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return GMMR0UpdateReservationReq(pVM, (PGMMUPDATERESERVATIONREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0AllocatePagesReq(pVM, (PGMMALLOCATEPAGESREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0FreePagesReq(pVM, (PGMMFREEPAGESREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0BalloonedPagesReq(pVM, (PGMMBALLOONEDPAGESREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0DeflatedBalloon(pVM, (uint32_t)u64Arg);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0MapUnmapChunkReq(pVM, (PGMMMAPUNMAPCHUNKREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * A quick GCFGM mock-up.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /** @todo GCFGM with proper access control, ring-3 management interface and all that. */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync rc = GVMMR0SetConfig(pReq->pSession, &pReq->szName[0], pReq->u64Value);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync //if (rc == VERR_CFGM_VALUE_NOT_FOUND)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync // rc = GMMR0SetConfig(pReq->pSession, &pReq->szName[0], pReq->u64Value);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync rc = GVMMR0QueryConfig(pReq->pSession, &pReq->szName[0], &pReq->u64Value);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync //if (rc == VERR_CFGM_VALUE_NOT_FOUND)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync // rc = GMMR0QueryConfig(pReq->pSession, &pReq->szName[0], &pReq->u64Value);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Requests to the internal networking service.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReq || !vmmR0IsValidSession(pVM, pReq->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFCLOSEREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfCloseReq(g_pIntNet, pSession, (PINTNETIFCLOSEREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFGETRING3BUFFERREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfGetRing3BufferReq(g_pIntNet, pSession, (PINTNETIFGETRING3BUFFERREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfSetPromiscuousModeReq(g_pIntNet, pSession, (PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETMACADDRESSREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfSetMacAddressReq(g_pIntNet, pSession, (PINTNETIFSETMACADDRESSREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETACTIVEREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfSetActiveReq(g_pIntNet, pSession, (PINTNETIFSETACTIVEREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSENDREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfSendReq(g_pIntNet, pSession, (PINTNETIFSENDREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFWAITREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfWaitReq(g_pIntNet, pSession, (PINTNETIFWAITREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync#endif /* VBOX_WITH_INTERNAL_NETWORKING */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * For profiling.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * For testing Ring-0 APIs invoked in this environment.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /** @todo make new test */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * We're returning VERR_NOT_SUPPORT here so we've got something else
cba6719bd64ec749967bbe931230452664109857vboxsync * than -1 which the interrupt gate glue code might return.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync Log(("operation %#x is not supported\n", enmOperation));
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync * Argument for vmmR0EntryExWrapper containing the argument s ofr VMMR0EntryEx.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync/** Pointer to a vmmR0EntryExWrapper argument package. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * This is just a longjmp wrapper function for VMMR0EntryEx calls.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @returns VBox status code.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @param pvArgs The argument package
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM,
9496f2d398b49813176939d7a339ae513d5175efvboxsync * The Ring 0 entry point, called by the support library (SUP).
68a4ee3a31a0807abd03eae881c1bbaf4d42ee6dvboxsync * @returns VBox status code.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @param pVM The VM to operate on.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @param enmOperation Which operation to execute.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @param pReq This points to a SUPVMMR0REQHDR packet. Optional.
caf54c14752060b187e3fca12a6f71f4b13126b8vboxsync * @param u64Arg Some simple constant argument.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * @param pSession The session of the caller.
68a4ee3a31a0807abd03eae881c1bbaf4d42ee6dvboxsync * @remarks Assume called with interrupts _enabled_.
9496f2d398b49813176939d7a339ae513d5175efvboxsyncVMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Requests that should only happen on the EMT thread will be
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * wrapped in a setjmp so we can assert without causing trouble.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** @todo validate this EMT claim... GVM knows. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return vmmR0CallHostSetJmpEx(&pVM->vmm.s.CallHostR0JmpBuf, vmmR0EntryExWrapper, &Args);
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync return vmmR0EntryExWorker(pVM, enmOperation, pReq, u64Arg, pSession);
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync * Internal R0 logger worker: Flush logger.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pLogger The logger instance to flush.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @remark This function must be exported!
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Convert the pLogger into a VM handle and 'call' back to Ring-3.
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync * (This is a bit paranoid code.)
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync PVMMR0LOGGER pR0Logger = (PVMMR0LOGGER)((uintptr_t)pLogger - RT_OFFSETOF(VMMR0LOGGER, Logger));
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync SUPR0Printf("vmmR0LoggerFlush: pLogger=%p!\n", pLogger);
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync SUPR0Printf("vmmR0LoggerFlush: pVM=%p! pVMR0=%p! pLogger=%p\n", pVM, pVM->pVMR0, pLogger);
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync * Check that the jump buffer is armed.
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync SUPR0Printf("vmmR0LoggerFlush: Jump buffer isn't armed!\n");
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync VMMR0CallHost(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync * Jump back to ring-3 if we're the EMT and the longjmp is armed.
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync * @returns true if the breakpoint should be hit, false if it should be ignored.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @remark The RTDECL() makes this a bit difficult to override on windows. Sorry.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return true;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return false;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Override this so we can push it up to ring-3.
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync * @param pszExpr Expression. Can be NULL.
efff36b306e370346025647a158689021df2e1d1vboxsync * @param uLine Location line number.
efff36b306e370346025647a158689021df2e1d1vboxsync * @param pszFile Location file name.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param pszFunction Location function name.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncDECLEXPORT(void) RTCALL AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync "Expression: %s\n"
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync "Location : %s(%d) %s\n",
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync "Expression: %s\n"
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync "Location : %s(%d) %s\n",
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync RTStrPrintf(pVM->vmm.s.szRing0AssertMsg1, sizeof(pVM->vmm.s.szRing0AssertMsg1),
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync "\n!!R0-Assertion Failed!!\n"
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync "Expression: %s\n"
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync "Location : %s(%d) %s\n",
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync * Callback for RTLogFormatV which writes to the ring-3 log port.
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync * See PFNLOGOUTPUT() for details.
27b178e99b06a68ef52353b15bc647674d2006bcvboxsyncstatic DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars)
a3369a746b56a8966dd78619f4d191c9662f400dvboxsyncDECLEXPORT(void) RTCALL AssertMsg2(const char *pszFormat, ...)
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync PRTLOGGER pLog = RTLogDefaultInstance(); /** @todo we want this for release as well! */