VMMR0.cpp revision 9a61edc05d8198a9990a095b5fc40cb09facc44e
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * VMM - Host Context Ring 0.
f14d3c62ebf4ccb64bd11528e5c4ec60b4528a1avboxsync * Copyright (C) 2006-2012 Oracle Corporation
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * available from http://www.virtualbox.org. This file is free software;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * you can redistribute it and/or modify it under the terms of the GNU
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * General Public License (GPL) as published by the Free Software
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/*******************************************************************************
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync* Header Files *
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync*******************************************************************************/
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#if defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/*******************************************************************************
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync* Internal Functions *
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync*******************************************************************************/
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#if defined(RT_ARCH_X86) && (defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/*******************************************************************************
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync* Global Variables *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync*******************************************************************************/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** Drag in necessary library bits.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * The runtime lives here (in VMMR0.r0) and VBoxDD*R0.r0 links against us. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync#if defined(RT_ARCH_X86) && (defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD))
400d70dc1edb0f6d2a9d3a860b1b43f0b2cdfb39vboxsync/* Dependency information for the native solaris loader. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Initialize the module.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * This is called when we're first loaded.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns 0 on success.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns VBox status on failure.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param hMod Image handle for use in APIs.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * The first thing to do is register the static tracepoints.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * (Deregistration is automatic.)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int rc2 = SUPR0TracerRegisterModule(hMod, &g_VTGObjHeader);
ce5210fe822f74de78c3dddc74f32a2cabcee5fdvboxsync * Initialize the VMM, GVMM, GMM, HM, PGM (Darwin) and INTNET.
3ca89d9d8c4fc158ba28bdf82c9cc3697625ce12vboxsync * Bail out.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogRel(("ModuleInit: CPUMR0ModuleInit -> %Rrc\n", rc));
f350b7cf96f1e2f3b0cfd34cfe8726c754f43584vboxsync LogRel(("ModuleInit: PciRawR0Init -> %Rrc\n", rc));
b8908d384db2324f04a2f68a13e67ea32ebf609avboxsync LogRel(("ModuleInit: IntNetR0Init -> %Rrc\n", rc));
b603b2af577731f9f825ba3681cd5b728bb1d1d4vboxsync LogRel(("ModuleInit: PGMR0DynMapInit -> %Rrc\n", rc));
3ca89d9d8c4fc158ba28bdf82c9cc3697625ce12vboxsync LogRel(("ModuleInit: PGMRegisterStringFormatTypes -> %Rrc\n", rc));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogRel(("ModuleInit: vmmInitFormatTypes -> %Rrc\n", rc));
6f6e182fde44ac8c4f95d8684e10fbbea937f26evboxsync * Terminate the module.
6f6e182fde44ac8c4f95d8684e10fbbea937f26evboxsync * This is called when we're finally unloaded.
20fc4a350a4a8e56ffaac6cf57dcd677a7ac36c5vboxsync * @param hMod Image handle for use in APIs.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Terminate the CPUM module (Local APIC cleanup).
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Terminate the internal network service.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * PGM (Darwin), HM and PciRaw global cleanup.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Destroy the GMM and GVMM instances.
f14d3c62ebf4ccb64bd11528e5c4ec60b4528a1avboxsync * Initiates the R0 driver for a particular VM instance.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns VBox status code.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVM Pointer to the VM.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param uSvnRev The SVN revision of the ring-3 part.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param uBuildType Build type indicator.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @thread EMT.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncstatic int vmmR0InitVM(PVM pVM, uint32_t uSvnRev, uint32_t uBuildType)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Match the SVN revisions and build type.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogRel(("VMMR0InitVM: Revision mismatch, r3=%d r0=%d\n", uSvnRev, VMMGetSvnRev()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync SUPR0Printf("VMMR0InitVM: Revision mismatch, r3=%d r0=%d\n", uSvnRev, VMMGetSvnRev());
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogRel(("VMMR0InitVM: Build type mismatch, r3=%#x r0=%#x\n", uBuildType, vmmGetBuildType()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync SUPR0Printf("VMMR0InitVM: Build type mismatch, r3=%#x r0=%#x\n", uBuildType, vmmGetBuildType());
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Register the EMT R0 logger instance for VCPU 0.
f14d3c62ebf4ccb64bd11528e5c4ec60b4528a1avboxsync# if 0 /* testing of the logger. */
f14d3c62ebf4ccb64bd11528e5c4ec60b4528a1avboxsync LogCom(("vmmR0InitVM: before %p\n", RTLogDefaultInstance()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: pfnFlush=%p actual=%p\n", pR0Logger->Logger.pfnFlush, vmmR0LoggerFlush));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: pfnLogger=%p actual=%p\n", pR0Logger->Logger.pfnLogger, vmmR0LoggerWrapper));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: offScratch=%d fFlags=%#x fDestFlags=%#x\n", pR0Logger->Logger.offScratch, pR0Logger->Logger.fFlags, pR0Logger->Logger.fDestFlags));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: after %p reg\n", RTLogDefaultInstance()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogSetDefaultInstanceThread(NULL, pVM->pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: after %p dereg\n", RTLogDefaultInstance()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: returned successfully from direct logger call.\n"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: returned successfully from direct flush call.\n"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: after %p reg2\n", RTLogDefaultInstance()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: returned successfully from direct logger call (2). offScratch=%d\n", pR0Logger->Logger.offScratch));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogSetDefaultInstanceThread(NULL, pVM->pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: after %p dereg2\n", RTLogDefaultInstance()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogLoggerEx(&pR0Logger->Logger, 0, ~0U, "hello ring-0 logger (RTLogLoggerEx)\n");
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: RTLogLoggerEx returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogPrintf("hello ring-0 logger (RTLogPrintf)\n");
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogCom(("vmmR0InitVM: RTLogPrintf returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Log(("Switching to per-thread logging instance %p (key=%p)\n", &pR0Logger->Logger, pVM->pSession));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* LOG_ENABLED */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Check if the host supports high resolution timers or not.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Initialize the per VM data for GVMM and GMM.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// if (RT_SUCCESS(rc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// rc = GMMR0InitPerVMData(pVM);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Init HM, CPUM and PGM (Darwin only).
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* bail out */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogSetDefaultInstanceThread(NULL, (uintptr_t)pVM->pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Terminates the R0 bits for a particular VM instance.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * This is normally called by ring-3 as part of the VM termination process, but
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * may alternatively be called during the support driver session cleanup when
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * the VM object is destroyed (see GVMM).
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns VBox status code.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVM Pointer to the VM.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pGVM Pointer to the global VM structure. Optional.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @thread EMT or session clean up thread.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Tell GVMM what we're up to and check that we only do this once.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** @todo I wish to call PGMR0PhysFlushHandyPages(pVM, &pVM->aCpus[idCpu])
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * here to make sure we don't leak any shared pages if we crash... */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Deregister the logger.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTLogSetDefaultInstanceThread(NULL, (uintptr_t)pVM->pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Creates R0 thread-context hooks for the current EMT thread.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns VBox status code.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVCpu Pointer to the VMCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @thread EMT.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncVMMR0DECL(int) VMMR0ThreadCtxHooksCreate(PVMCPU pVCpu)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pVCpu->vmm.s.hR0ThreadCtx == NIL_RTTHREADCTX);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#if 0 /* Not stable yet. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int rc = RTThreadCtxHooksCreate(&pVCpu->vmm.s.hR0ThreadCtx);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Log(("RTThreadCtxHooksCreate failed! rc=%Rrc pVCpu=%p idCpu=%RU32\n", rc, pVCpu, pVCpu->idCpu));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Releases the object reference for the thread-context hook.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVCpu Pointer to the VMCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @remarks Can be called from any thread.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncVMMR0DECL(void) VMMR0ThreadCtxHooksRelease(PVMCPU pVCpu)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTThreadCtxHooksRelease(pVCpu->vmm.s.hR0ThreadCtx);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Registers the thread-context hook for this VCPU.
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync * @returns VBox status code.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVCpu Pointer to the VMCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pfnThreadHook Pointer to the thread-context callback.
f5eadb22976c1f9813300e4042b8255cfaef7e19vboxsync * @thread EMT.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncVMMR0DECL(int) VMMR0ThreadCtxHooksRegister(PVMCPU pVCpu, PFNRTTHREADCTXHOOK pfnThreadHook)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return RTThreadCtxHooksRegister(pVCpu->vmm.s.hR0ThreadCtx, pfnThreadHook, pVCpu);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Deregisters the thread-context hook for this VCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns VBox status code.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pVCpu Pointer to the VMCPU.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @thread EMT.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncVMMR0DECL(int) VMMR0ThreadCtxHooksDeregister(PVMCPU pVCpu)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTThreadCtxHooksDeregister(pVCpu->vmm.s.hR0ThreadCtx);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Whether thread-context hooks are created (implying they're supported) on this
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * platform.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @returns true if the hooks are created, false otherwise.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pVCpu Pointer to the VMCPU.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @remarks Can be called from any thread.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncVMMR0DECL(bool) VMMR0ThreadCtxHooksAreCreated(PVMCPU pVCpu)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return pVCpu->vmm.s.hR0ThreadCtx != NIL_RTTHREADCTX;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Whether thread-context hooks are registered for this VCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns true if registered, false otherwise.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVCpu Pointer to the VMCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncVMMR0DECL(bool) VMMR0ThreadCtxHooksAreRegistered(PVMCPU pVCpu)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTThreadCtxHooksAreRegistered(pVCpu->vmm.s.hR0ThreadCtx);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * VMM ring-0 thread-context callback.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * This does common HM state updating and calls the HM-specific thread-context
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * callback.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param enmEvent The thread-context event.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pvUser Opaque pointer to the VMCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncstatic void vmmR0ThreadCtxCallback(RTTHREADCTXEVENT enmEvent, void *pvUser)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** @todo Linux may call us with preemption enabled (really!) but technically we
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * cannot get preempted here, otherwise we end up in an infinite recursion
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * scenario (i.e. preempted in resume hook -> preempt hook -> resume hook... ad
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * infinitum). Let's just disable preemption for now...
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* We need to update the VCPU <-> host CPU mapping. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Invoke the HM-specific thread-context callback. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Restore preemption. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Sigh. See VMMGetCpu() used by VMCPU_ASSERT_EMT(). We cannot let several VCPUs
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * have the same host CPU associated with it.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* fallthru, no break! */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Invoke the HM-specific thread-context callback. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Record return code statistics
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVM Pointer to the VM.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVCpu Pointer to the VMCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param rc The status code.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncstatic void vmmR0RecordRC(PVM pVM, PVMCPU pVCpu, int rc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Collect statistics.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetInterruptHyper);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetRingSwitchInt);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetStaleSelector);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetMMIOReadWrite);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetMMIOPatchRead);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetMMIOPatchWrite);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetIOBlockEmulate);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPatchEmulate);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPatchIretIRQ);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetRescheduleREM);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else if (VM_FF_IS_PENDING(pVM, VM_FF_PGM_NEED_HANDY_PAGES))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3HandyPages);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3PDMQueues);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else if (VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3Rendezvous);
f14d3c62ebf4ccb64bd11528e5c4ec60b4528a1avboxsync else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TIMER))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_PDM_CRITSECT))
f14d3c62ebf4ccb64bd11528e5c4ec60b4528a1avboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3CritSect);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TO_R3))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3Unknown);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetTimerPending);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetInterruptPending);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPDMCritSectEnter);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPGMPoolGrow);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPGMMapChunk);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPGMAllocHandy);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case VMMCALLRING3_REM_REPLAY_HANDLER_NOTIFICATIONS:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallVMSetError);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallVMSetRuntimeError);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPATMDuplicateFn);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPGMChangeMode);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPGMFlushPending);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPendingRequest);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_STATISTICS */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Unused ring-0 entry point that used to be called from the interrupt gate.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Will be removed one of the next times we do a major SUPDrv version bump.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns VBox status code.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVM Pointer to the VM.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param enmOperation Which operation to execute.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pvArg Argument to the operation.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @remarks Assume called with interrupts disabled.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncVMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg)
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * We're returning VERR_NOT_SUPPORT here so we've got something else
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * than -1 which the interrupt gate glue code might return.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync Log(("operation %#x is not supported\n", enmOperation));
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * The Ring 0 entry point, called by the fast-ioctl path.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @param pVM Pointer to the VM.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync * The return code is stored in pVM->vmm.s.iLastGZRc.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync * @param idCpu The Virtual CPU ID of the calling EMT.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync * @param enmOperation Which operation to execute.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync * @remarks Assume called with interrupts _enabled_.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsyncVMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation)
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync * Switch to GC and run guest raw mode code.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync * Disable interrupts before doing the world switch.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* Some safety precautions first. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync pVCpu->vmm.s.iLastGZRc = VERR_PGM_NO_CR3_SHADOW_ROOT;
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* Disable preemption and update the periodic preemption timer. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu));
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync /* We might need to disable VT-x if the active switcher turns off paging. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync int rc = HMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync SUPR0TracerUmodProbeFire(pVM->pSession, &pVCpu->vmm.s.TracerCtx);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /* Re-enable VT-x if previously turned off. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Run guest code using the available hardware acceleration technology.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Disable interrupts before we do anything interesting. On Windows we avoid
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * this by having the support driver raise the IRQL before calling us, this way
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * we hope to get away with page faults and later calling into the kernel.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* Update the VCPU <-> host CPU mapping before doing anything else. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu));
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /* Lazy registration of ring 0 loggers. */
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /* Register thread-context hooks if required. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = VMMR0ThreadCtxHooksRegister(pVCpu, vmmR0ThreadCtxCallback);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* Enter HM context. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* When preemption hooks are in place, enable preemption now that we're in HM context. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* Setup the longjmp machinery and execute guest code. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync rc = vmmR0CallRing3SetJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, HMR0RunGuestCode, pVM, pVCpu);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* Leave HM context. This deregisters thread-context hooks if any. */
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync if (RT_UNLIKELY( VMCPU_GET_STATE(pVCpu) != VMCPUSTATE_STARTED_HM
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync && RT_SUCCESS_NP(rc) && rc != VINF_VMM_CALL_HOST ))
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /* Manual assert as normal assertions are going to crash in this case. */
d6c4b5eecea7735227dc41255d4e742543ddc86fvboxsync RTStrPrintf(pVM->vmm.s.szRing0AssertMsg2, sizeof(pVM->vmm.s.szRing0AssertMsg2),
d6c4b5eecea7735227dc41255d4e742543ddc86fvboxsync "Got VMCPU state %d expected %d.\n", VMCPU_GET_STATE(pVCpu), VMCPUSTATE_STARTED_HM);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* System is about to go into suspend mode; go back to ring 3. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* Clear the VCPU <-> host CPU mapping as we've left HM context. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* No special action required for external interrupts, just return. */
79fe674227c3f2b82ab22a6b7d340283b610fb83vboxsync * For profiling.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Impossible.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Validates a session or VM session argument.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @returns true / false accordingly.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @param pVM Pointer to the VM.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @param pSession The session argument.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsyncDECLINLINE(bool) vmmR0IsValidSession(PVM pVM, PSUPDRVSESSION pClaimedSession, PSUPDRVSESSION pSession)
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* This must be set! */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return false;
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* Only one out of the two. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return false;
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * VMMR0EntryEx worker function, either called directly or when ever possible
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * called thru a longjmp so we can exit safely on failure.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @returns VBox status code.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @param pVM Pointer to the VM.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync * @param idCpu Virtual CPU ID argument. Must be NIL_VMCPUID if pVM
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * is NIL_RTR0PTR, and may be NIL_VMCPUID if it isn't
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync * @param enmOperation Which operation to execute.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @param pReqHdr This points to a SUPVMMR0REQHDR packet. Optional.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * The support driver validates this if it's present.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @param u64Arg Some simple constant argument.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @param pSession The session of the caller.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * @remarks Assume called with interrupts _enabled_.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsyncstatic int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession)
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Common VM pointer validation.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p! (op=%d)\n", pVM, enmOperation);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync if (RT_UNLIKELY( pVM->enmVMState < VMSTATE_CREATING
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p:{enmVMState=%d, .pVMR0=%p}! (op=%d)\n",
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync if (RT_UNLIKELY(idCpu >= pVM->cCpus && idCpu != NIL_VMCPUID))
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid idCpu (%u vs cCpus=%u)\n", idCpu, pVM->cCpus);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid idCpu=%u\n", idCpu);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * GVM requests
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GVMMR0SchedWakeUpAndPokeCpusReq(pVM, (PGVMMSCHEDWAKEUPANDPOKECPUSREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Initialize the R0 part of a VM instance.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync return vmmR0InitVM(pVM, RT_LODWORD(u64Arg), RT_HIDWORD(u64Arg));
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Terminate the R0 part of a VM instance.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Attempt to enable hm mode and check the current setting.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Setup the hardware accelerated session.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Switch to RC to execute Hypervisor function.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync /* We might need to disable VT-x if the active switcher turns off paging. */
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync rc = HMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
f65d92209d8ab9f6093c0e2a90e7d5b73a2254fevboxsync /* Re-enable VT-x if previously turned off. */
f65d92209d8ab9f6093c0e2a90e7d5b73a2254fevboxsync /** @todo dispatch interrupts? */
f65d92209d8ab9f6093c0e2a90e7d5b73a2254fevboxsync * PGM wrappers.
f65d92209d8ab9f6093c0e2a90e7d5b73a2254fevboxsync return PGMR0PhysAllocateHandyPages(pVM, &pVM->aCpus[idCpu]);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return PGMR0PhysFlushHandyPages(pVM, &pVM->aCpus[idCpu]);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return PGMR0PhysAllocateLargeHandyPage(pVM, &pVM->aCpus[idCpu]);
980eeb78f6811c935c7ebbe33de92f757ec3bc78vboxsync * GMM wrappers.
980eeb78f6811c935c7ebbe33de92f757ec3bc78vboxsync return GMMR0InitialReservationReq(pVM, idCpu, (PGMMINITIALRESERVATIONREQ)pReqHdr);
f7f5cd7b1e530eb5636da51c974b48ae0c1775b3vboxsync return GMMR0UpdateReservationReq(pVM, idCpu, (PGMMUPDATERESERVATIONREQ)pReqHdr);
f7f5cd7b1e530eb5636da51c974b48ae0c1775b3vboxsync return GMMR0AllocatePagesReq(pVM, idCpu, (PGMMALLOCATEPAGESREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GMMR0FreePagesReq(pVM, idCpu, (PGMMFREEPAGESREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GMMR0FreeLargePageReq(pVM, idCpu, (PGMMFREELARGEPAGEREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GMMR0QueryHypervisorMemoryStatsReq(pVM, (PGMMMEMSTATSREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GMMR0QueryMemoryStatsReq(pVM, idCpu, (PGMMMEMSTATSREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GMMR0BalloonedPagesReq(pVM, idCpu, (PGMMBALLOONEDPAGESREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GMMR0MapUnmapChunkReq(pVM, (PGMMMAPUNMAPCHUNKREQ)pReqHdr);
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync return GMMR0SeedChunk(pVM, idCpu, (RTR3PTR)u64Arg);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return GMMR0RegisterSharedModuleReq(pVM, idCpu, (PGMMREGISTERSHAREDMODULEREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return GMMR0UnregisterSharedModuleReq(pVM, idCpu, (PGMMUNREGISTERSHAREDMODULEREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync Assert(pVCpu->hNativeThreadR0 == RTThreadNativeSelf());
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /* Make sure that log flushes can jump back to ring-3; annoying to get an incomplete log (this is risky though as the code doesn't take this into account). */
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /* Todo: this can have bad side effects for unexpected jumps back to r3. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync rc = vmmR0CallRing3SetJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, GMMR0CheckSharedModules, pVM, pVCpu); /* this may resume code. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync || (rc == VINF_VMM_CALL_HOST && pVCpu->vmm.s.enmCallRing3Operation == VMMCALLRING3_VMM_LOGGER_FLUSH));
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GMMR0FindDuplicatePageReq(pVM, (PGMMFINDDUPLICATEPAGEREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return GMMR0QueryStatisticsReq(pVM, (PGMMQUERYSTATISTICSSREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return GMMR0ResetStatisticsReq(pVM, (PGMMRESETSTATISTICSSREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync * A quick GCFGM mock-up.
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /** @todo GCFGM with proper access control, ring-3 management interface and all that. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync if (pVM || !pReqHdr || u64Arg || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync rc = GVMMR0SetConfig(pReq->pSession, &pReq->szName[0], pReq->u64Value);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync //if (rc == VERR_CFGM_VALUE_NOT_FOUND)
f14d3c62ebf4ccb64bd11528e5c4ec60b4528a1avboxsync // rc = GMMR0SetConfig(pReq->pSession, &pReq->szName[0], pReq->u64Value);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync rc = GVMMR0QueryConfig(pReq->pSession, &pReq->szName[0], &pReq->u64Value);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync //if (rc == VERR_CFGM_VALUE_NOT_FOUND)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync // rc = GMMR0QueryConfig(pReq->pSession, &pReq->szName[0], &pReq->u64Value);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * PDM Wrappers.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync if (!pVM || !pReqHdr || u64Arg || idCpu != NIL_VMCPUID)
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync return PDMR0DriverCallReqHandler(pVM, (PPDMDRIVERCALLREQHANDLERREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync if (!pVM || !pReqHdr || u64Arg || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return PDMR0DeviceCallReqHandler(pVM, (PPDMDEVICECALLREQHANDLERREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync * Requests to the internal networking service.
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync if (u64Arg || !pReq || !vmmR0IsValidSession(pVM, pReq->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFCLOSEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return IntNetR0IfCloseReq(pSession, (PINTNETIFCLOSEREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFGETBUFFERPTRSREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return IntNetR0IfGetBufferPtrsReq(pSession, (PINTNETIFGETBUFFERPTRSREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return IntNetR0IfSetPromiscuousModeReq(pSession, (PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr);
3ee1fadbf124a56daa99470bee91759440ef5da9vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETMACADDRESSREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return IntNetR0IfSetMacAddressReq(pSession, (PINTNETIFSETMACADDRESSREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETACTIVEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return IntNetR0IfSetActiveReq(pSession, (PINTNETIFSETACTIVEREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSENDREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return IntNetR0IfSendReq(pSession, (PINTNETIFSENDREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFWAITREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return IntNetR0IfWaitReq(pSession, (PINTNETIFWAITREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFWAITREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return IntNetR0IfAbortWaitReq(pSession, (PINTNETIFABORTWAITREQ)pReqHdr);
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync * Requests to host PCI driver service.
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PPCIRAWSENDREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync return PciRawR0ProcessReq(pSession, pVM, (PPCIRAWSENDREQ)pReqHdr);
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * For profiling.
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync * For testing Ring-0 APIs invoked in this environment.
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /** @todo make new test */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * We're returning VERR_NOT_SUPPORT here so we've got something else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * than -1 which the interrupt gate glue code might return.
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync Log(("operation %#x is not supported\n", enmOperation));
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * Argument for vmmR0EntryExWrapper containing the arguments for VMMR0EntryEx.
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync/** Pointer to a vmmR0EntryExWrapper argument package. */
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync * This is just a longjmp wrapper function for VMMR0EntryEx calls.
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync * @returns VBox status code.
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync * @param pvArgs The argument package
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsyncstatic DECLCALLBACK(int) vmmR0EntryExWrapper(void *pvArgs)
37e7010b28a4667800196960b59cd63b5434b7d7vboxsync return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * The Ring 0 entry point, called by the support library (SUP).
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @returns VBox status code.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pVM Pointer to the VM.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param idCpu Virtual CPU ID argument. Must be NIL_VMCPUID if pVM
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * is NIL_RTR0PTR, and may be NIL_VMCPUID if it isn't
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param enmOperation Which operation to execute.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pReq Pointer to the SUPVMMR0REQHDR packet. Optional.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param u64Arg Some simple constant argument.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @param pSession The session of the caller.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @remarks Assume called with interrupts _enabled_.
733c64713253004dc4de114e345c3e0b667b92ffvboxsyncVMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Requests that should only happen on the EMT thread will be
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * wrapped in a setjmp so we can assert without causing trouble.
733c64713253004dc4de114e345c3e0b667b92ffvboxsync /* These might/will be called before VMMR3Init. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* On the mac we might not have a valid jmp buf, so check these as well. */
9fbcdff887bd2d679720a8a50f5601df57b32b1bvboxsync /** @todo validate this EMT claim... GVM knows. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vmmR0CallRing3SetJmpEx(&pVCpu->vmm.s.CallRing3JmpBufR0, vmmR0EntryExWrapper, &Args);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vmmR0EntryExWorker(pVM, idCpu, enmOperation, pReq, u64Arg, pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Checks whether we've armed the ring-0 long jump machinery.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns @c true / @c false
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVCpu Pointer to the VMCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @thread EMT
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @sa VMMIsLongJumpArmed
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncVMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPU pVCpu)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Checks whether we've done a ring-3 long jump.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @returns @c true / @c false
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pVCpu Pointer to the VMCPU.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @thread EMT
f14d3c62ebf4ccb64bd11528e5c4ec60b4528a1avboxsyncVMMR0_INT_DECL(bool) VMMR0IsInRing3LongJump(PVMCPU pVCpu)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Internal R0 logger worker: Flush logger.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pLogger The logger instance to flush.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @remark This function must be exported!
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Convert the pLogger into a VM handle and 'call' back to Ring-3.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * (This is a bit paranoid code.)
# ifdef DEBUG
# ifdef DEBUG
if (pVCpu)
# ifdef RT_ARCH_X86
# ifdef DEBUG
# ifdef DEBUG
#ifdef LOG_ENABLED
#ifdef LOG_ENABLED
if (pVM)
if (pVCpu)
#ifdef RT_ARCH_X86
#ifdef RT_OS_LINUX
DECLEXPORT(void) RTCALL RTAssertMsg1Weak(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
if (pVM)
return cbChars;
if (pLog)
if (pLog)
if (pVM)
RTStrPrintfV(pVM->vmm.s.szRing0AssertMsg2, sizeof(pVM->vmm.s.szRing0AssertMsg2), pszFormat, vaCopy);