VMMR0.cpp revision f26998e651e8194c412c6de164723b32da1bff3e
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * VMM - Host Context Ring 0.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Copyright (C) 2006-2012 Oracle Corporation
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * available from http://www.virtualbox.org. This file is free software;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * General Public License (GPL) as published by the Free Software
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync/*******************************************************************************
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync* Header Files *
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync*******************************************************************************/
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync#if defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync/*******************************************************************************
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync* Internal Functions *
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync*******************************************************************************/
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync#if defined(RT_ARCH_X86) && (defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD))
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync/*******************************************************************************
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync* Global Variables *
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync*******************************************************************************/
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync/** Drag in necessary library bits.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * The runtime lives here (in VMMR0.r0) and VBoxDD*R0.r0 links against us. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync#if defined(RT_ARCH_X86) && (defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD))
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync/* Dependency information for the native solaris loader. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Initialize the module.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * This is called when we're first loaded.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @returns 0 on success.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @returns VBox status on failure.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param hMod Image handle for use in APIs.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * The first thing to do is register the static tracepoints.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * (Deregistration is automatic.)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync int rc2 = SUPR0TracerRegisterModule(hMod, &g_VTGObjHeader);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Display the CMOS debug code.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync LogRel(("CMOS Debug Code: %#x (%d)\n", bDebugCode, bDebugCode));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync RTLogComPrintf("CMOS Debug Code: %#x (%d)\n", bDebugCode, bDebugCode);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Initialize the VMM, GVMM, GMM, HM, PGM (Darwin) and INTNET.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Bail out.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync LogRel(("ModuleInit: CPUMR0ModuleInit -> %Rrc\n", rc));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync LogRel(("ModuleInit: PciRawR0Init -> %Rrc\n", rc));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync LogRel(("ModuleInit: IntNetR0Init -> %Rrc\n", rc));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync LogRel(("ModuleInit: PGMR0DynMapInit -> %Rrc\n", rc));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync LogRel(("ModuleInit: PGMRegisterStringFormatTypes -> %Rrc\n", rc));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync LogRel(("ModuleInit: vmmInitFormatTypes -> %Rrc\n", rc));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Terminate the module.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * This is called when we're finally unloaded.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param hMod Image handle for use in APIs.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Terminate the CPUM module (Local APIC cleanup).
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Terminate the internal network service.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync * PGM (Darwin), HM and PciRaw global cleanup.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Destroy the GMM and GVMM instances.
270236340676d2385b27ea992e07fcb643bb78b6vboxsync * Initiates the R0 driver for a particular VM instance.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @returns VBox status code.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pVM Pointer to the VM.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param uSvnRev The SVN revision of the ring-3 part.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param uBuildType Build type indicator.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @thread EMT.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncstatic int vmmR0InitVM(PVM pVM, uint32_t uSvnRev, uint32_t uBuildType)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Match the SVN revisions and build type.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync LogRel(("VMMR0InitVM: Revision mismatch, r3=%d r0=%d\n", uSvnRev, VMMGetSvnRev()));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync SUPR0Printf("VMMR0InitVM: Revision mismatch, r3=%d r0=%d\n", uSvnRev, VMMGetSvnRev());
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync LogRel(("VMMR0InitVM: Build type mismatch, r3=%#x r0=%#x\n", uBuildType, vmmGetBuildType()));
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync SUPR0Printf("VMMR0InitVM: Build type mismatch, r3=%#x r0=%#x\n", uBuildType, vmmGetBuildType());
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync * Register the EMT R0 logger instance for VCPU 0.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync# if 0 /* testing of the logger. */
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: before %p\n", RTLogDefaultInstance()));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: pfnFlush=%p actual=%p\n", pR0Logger->Logger.pfnFlush, vmmR0LoggerFlush));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: pfnLogger=%p actual=%p\n", pR0Logger->Logger.pfnLogger, vmmR0LoggerWrapper));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: offScratch=%d fFlags=%#x fDestFlags=%#x\n", pR0Logger->Logger.offScratch, pR0Logger->Logger.fFlags, pR0Logger->Logger.fDestFlags));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: after %p reg\n", RTLogDefaultInstance()));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync RTLogSetDefaultInstanceThread(NULL, pVM->pSession);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: after %p dereg\n", RTLogDefaultInstance()));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: returned successfully from direct logger call.\n"));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: returned successfully from direct flush call.\n"));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: after %p reg2\n", RTLogDefaultInstance()));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: returned successfully from direct logger call (2). offScratch=%d\n", pR0Logger->Logger.offScratch));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync RTLogSetDefaultInstanceThread(NULL, pVM->pSession);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: after %p dereg2\n", RTLogDefaultInstance()));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync RTLogLoggerEx(&pR0Logger->Logger, 0, ~0U, "hello ring-0 logger (RTLogLoggerEx)\n");
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: RTLogLoggerEx returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync RTLogPrintf("hello ring-0 logger (RTLogPrintf)\n");
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync LogCom(("vmmR0InitVM: RTLogPrintf returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync Log(("Switching to per-thread logging instance %p (key=%p)\n", &pR0Logger->Logger, pVM->pSession));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync#endif /* LOG_ENABLED */
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync * Check if the host supports high resolution timers or not.
270236340676d2385b27ea992e07fcb643bb78b6vboxsync * Initialize the per VM data for GVMM and GMM.
270236340676d2385b27ea992e07fcb643bb78b6vboxsync// if (RT_SUCCESS(rc))
270236340676d2385b27ea992e07fcb643bb78b6vboxsync// rc = GMMR0InitPerVMData(pVM);
270236340676d2385b27ea992e07fcb643bb78b6vboxsync * Init HM, CPUM and PGM (Darwin only).
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* bail out */
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync RTLogSetDefaultInstanceThread(NULL, (uintptr_t)pVM->pSession);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * Terminates the R0 bits for a particular VM instance.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * This is normally called by ring-3 as part of the VM termination process, but
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * may alternatively be called during the support driver session cleanup when
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * the VM object is destroyed (see GVMM).
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @returns VBox status code.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @param pVM Pointer to the VM.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @param pGVM Pointer to the global VM structure. Optional.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @thread EMT or session clean up thread.
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync * Tell GVMM what we're up to and check that we only do this once.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync /** @todo I wish to call PGMR0PhysFlushHandyPages(pVM, &pVM->aCpus[idCpu])
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * here to make sure we don't leak any shared pages if we crash... */
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * Deregister the logger.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync RTLogSetDefaultInstanceThread(NULL, (uintptr_t)pVM->pSession);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * Creates R0 thread-context hooks for the current EMT thread.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @returns VBox status code.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @param pVCpu Pointer to the VMCPU.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @thread EMT.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsyncVMMR0DECL(int) VMMR0ThreadCtxHooksCreate(PVMCPU pVCpu)
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync Assert(pVCpu->vmm.s.hR0ThreadCtx == NIL_RTTHREADCTX);
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync int rc = RTThreadCtxHooksCreate(&pVCpu->vmm.s.hR0ThreadCtx);
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync Log(("RTThreadCtxHooksCreate failed! rc=%Rrc pVCpu=%p idCpu=%RU32\n", rc, pVCpu, pVCpu->idCpu));
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync * Releases the object reference for the thread-context hook.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @param pVCpu Pointer to the VMCPU.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @remarks Can be called from any thread.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsyncVMMR0DECL(void) VMMR0ThreadCtxHooksRelease(PVMCPU pVCpu)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync RTThreadCtxHooksRelease(pVCpu->vmm.s.hR0ThreadCtx);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync * Registers the thread-context hook for this VCPU.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync * @returns VBox status code.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync * @param pVCpu Pointer to the VMCPU.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync * @param pfnThreadHook Pointer to the thread-context callback.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync * @thread EMT.
270236340676d2385b27ea992e07fcb643bb78b6vboxsyncVMMR0DECL(int) VMMR0ThreadCtxHooksRegister(PVMCPU pVCpu, PFNRTTHREADCTXHOOK pfnThreadHook)
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync return RTThreadCtxHooksRegister(pVCpu->vmm.s.hR0ThreadCtx, pfnThreadHook, pVCpu);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * Deregisters the thread-context hook for this VCPU.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @returns VBox status code.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @param pVCpu Pointer to the VMCPU.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @thread EMT.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsyncVMMR0DECL(int) VMMR0ThreadCtxHooksDeregister(PVMCPU pVCpu)
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync return RTThreadCtxHooksDeregister(pVCpu->vmm.s.hR0ThreadCtx);
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync * Whether thread-context hooks are created (implying they're supported) on this
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * platform.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @returns true if the hooks are created, false otherwise.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @param pVCpu Pointer to the VMCPU.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @remarks Can be called from any thread.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsyncVMMR0DECL(bool) VMMR0ThreadCtxHooksAreCreated(PVMCPU pVCpu)
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync return pVCpu->vmm.s.hR0ThreadCtx != NIL_RTTHREADCTX;
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * Whether thread-context hooks are registered for this VCPU.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync * @returns true if registered, false otherwise.
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync * @param pVCpu Pointer to the VMCPU.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsyncVMMR0DECL(bool) VMMR0ThreadCtxHooksAreRegistered(PVMCPU pVCpu)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return RTThreadCtxHooksAreRegistered(pVCpu->vmm.s.hR0ThreadCtx);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * VMM ring-0 thread-context callback.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * This does common HM state updating and calls the HM-specific thread-context
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * callback.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param enmEvent The thread-context event.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pvUser Opaque pointer to the VMCPU.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsyncstatic DECLCALLBACK(void) vmmR0ThreadCtxCallback(RTTHREADCTXEVENT enmEvent, void *pvUser)
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /** @todo Linux may call us with preemption enabled (really!) but technically we
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync * cannot get preempted here, otherwise we end up in an infinite recursion
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync * scenario (i.e. preempted in resume hook -> preempt hook -> resume hook... ad
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync * infinitum). Let's just disable preemption for now...
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* We need to update the VCPU <-> host CPU mapping. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* Invoke the HM-specific thread-context callback. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* Restore preemption. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* Invoke the HM-specific thread-context callback. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Sigh. See VMMGetCpu() used by VMCPU_ASSERT_EMT(). We cannot let several VCPUs
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * have the same host CPU associated with it.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* Invoke the HM-specific thread-context callback. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Record return code statistics
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pVM Pointer to the VM.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pVCpu Pointer to the VMCPU.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param rc The status code.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncstatic void vmmR0RecordRC(PVM pVM, PVMCPU pVCpu, int rc)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Collect statistics.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetInterruptHyper);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetRingSwitchInt);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetStaleSelector);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetMMIOReadWrite);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetMMIOPatchRead);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetMMIOPatchWrite);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetIOBlockEmulate);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPatchEmulate);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPatchIretIRQ);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetRescheduleREM);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync else if (VM_FF_IS_PENDING(pVM, VM_FF_PGM_NEED_HANDY_PAGES))
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3HandyPages);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3PDMQueues);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync else if (VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS))
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3Rendezvous);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TIMER))
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_PDM_CRITSECT))
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3CritSect);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TO_R3))
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetToR3Unknown);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetTimerPending);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetInterruptPending);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPDMCritSectEnter);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPGMPoolGrow);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPGMMapChunk);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallPGMAllocHandy);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync case VMMCALLRING3_REM_REPLAY_HANDLER_NOTIFICATIONS:
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallVMSetError);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZCallVMSetRuntimeError);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPATMDuplicateFn);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPGMChangeMode);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPGMFlushPending);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPendingRequest);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync#endif /* VBOX_WITH_STATISTICS */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Unused ring-0 entry point that used to be called from the interrupt gate.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Will be removed one of the next times we do a major SUPDrv version bump.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @returns VBox status code.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pVM Pointer to the VM.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param enmOperation Which operation to execute.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pvArg Argument to the operation.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @remarks Assume called with interrupts disabled.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncVMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * We're returning VERR_NOT_SUPPORT here so we've got something else
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * than -1 which the interrupt gate glue code might return.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Log(("operation %#x is not supported\n", enmOperation));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * The Ring 0 entry point, called by the fast-ioctl path.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pVM Pointer to the VM.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * The return code is stored in pVM->vmm.s.iLastGZRc.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param idCpu The Virtual CPU ID of the calling EMT.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param enmOperation Which operation to execute.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @remarks Assume called with interrupts _enabled_.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncVMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Switch to GC and run guest raw mode code.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Disable interrupts before doing the world switch.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* Some safety precautions first. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync pVCpu->vmm.s.iLastGZRc = VERR_PGM_NO_CR3_SHADOW_ROOT;
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* Disable preemption and update the periodic preemption timer. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* We might need to disable VT-x if the active switcher turns off paging. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync int rc = HMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync SUPR0TracerUmodProbeFire(pVM->pSession, &pVCpu->vmm.s.TracerCtx);
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* Re-enable VT-x if previously turned off. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync * Run guest code using the available hardware acceleration technology.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* Update the VCPU <-> host CPU mapping before doing anything else. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu));
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync /* Lazy registration of ring 0 loggers. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* Register thread-context hooks if required. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync rc = VMMR0ThreadCtxHooksRegister(pVCpu, vmmR0ThreadCtxCallback);
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* Enter HM context. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* When preemption hooks are in place, enable preemption now that we're in HM context. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* Setup the longjmp machinery and execute guest code. */
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync rc = vmmR0CallRing3SetJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, HMR0RunGuestCode, pVM, pVCpu);
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync /* Manual assert as normal assertions are going to crash in this case. */
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync if (RT_UNLIKELY( VMCPU_GET_STATE(pVCpu) != VMCPUSTATE_STARTED_HM
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync && RT_SUCCESS_NP(rc) && rc != VINF_VMM_CALL_HOST ))
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync RTStrPrintf(pVM->vmm.s.szRing0AssertMsg2, sizeof(pVM->vmm.s.szRing0AssertMsg2),
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync "Got VMCPU state %d expected %d.\n", VMCPU_GET_STATE(pVCpu), VMCPUSTATE_STARTED_HM);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync else if (RT_UNLIKELY(VMMR0ThreadCtxHooksAreRegistered(pVCpu)))
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync RTStrPrintf(pVM->vmm.s.szRing0AssertMsg2, sizeof(pVM->vmm.s.szRing0AssertMsg2),
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync "Thread-context hooks still registered! VCPU=%p Id=%u rc=%d.\n", pVCpu, pVCpu->idCpu, rc);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* System is about to go into suspend mode; go back to ring 3. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* Clear the VCPU <-> host CPU mapping as we've left HM context. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* No special action required for external interrupts, just return. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * For profiling.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Impossible.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Validates a session or VM session argument.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @returns true / false accordingly.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pVM Pointer to the VM.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync * @param pSession The session argument.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncDECLINLINE(bool) vmmR0IsValidSession(PVM pVM, PSUPDRVSESSION pClaimedSession, PSUPDRVSESSION pSession)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* This must be set! */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return false;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync /* Only one out of the two. */
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return false;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * VMMR0EntryEx worker function, either called directly or when ever possible
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * called thru a longjmp so we can exit safely on failure.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @returns VBox status code.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pVM Pointer to the VM.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param idCpu Virtual CPU ID argument. Must be NIL_VMCPUID if pVM
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * is NIL_RTR0PTR, and may be NIL_VMCPUID if it isn't
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param enmOperation Which operation to execute.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pReqHdr This points to a SUPVMMR0REQHDR packet. Optional.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * The support driver validates this if it's present.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param u64Arg Some simple constant argument.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @param pSession The session of the caller.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * @remarks Assume called with interrupts _enabled_.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncstatic int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Common VM pointer validation.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p! (op=%d)\n", pVM, enmOperation);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync if (RT_UNLIKELY( pVM->enmVMState < VMSTATE_CREATING
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p:{enmVMState=%d, .pVMR0=%p}! (op=%d)\n",
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync if (RT_UNLIKELY(idCpu >= pVM->cCpus && idCpu != NIL_VMCPUID))
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid idCpu (%u vs cCpus=%u)\n", idCpu, pVM->cCpus);
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid idCpu=%u\n", idCpu);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * GVM requests
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return GVMMR0SchedWakeUpAndPokeCpusReq(pVM, (PGVMMSCHEDWAKEUPANDPOKECPUSREQ)pReqHdr);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync * Initialize the R0 part of a VM instance.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return vmmR0InitVM(pVM, RT_LODWORD(u64Arg), RT_HIDWORD(u64Arg));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Terminate the R0 part of a VM instance.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Attempt to enable hm mode and check the current setting.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync * Setup the hardware accelerated session.
case VMMR0_DO_CALL_HYPERVISOR:
int rc;
bool fVTxDisabled;
return VERR_PGM_NO_CR3_SHADOW_ROOT;
return rc;
return rc;
return VERR_INVALID_CPU_ID;
return VERR_INVALID_CPU_ID;
return VERR_INVALID_CPU_ID;
if (idCpu != 0)
return VERR_INVALID_CPU_ID;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GMM_FREE_PAGES:
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_CPU_ID;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GMM_SEED_CHUNK:
if (pReqHdr)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_CPU_ID;
if (u64Arg)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_CPU_ID;
if (u64Arg)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_CPU_ID;
if ( u64Arg
|| pReqHdr)
return VERR_INVALID_PARAMETER;
#ifdef VBOX_WITH_PAGE_SHARING
return VERR_INVALID_CPU_ID;
if ( u64Arg
|| pReqHdr)
return VERR_INVALID_PARAMETER;
# ifdef DEBUG_sandervl
/* 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). */
rc = vmmR0CallRing3SetJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, GMMR0CheckSharedModules, pVM, pVCpu); /* this may resume code. */
|| (rc == VINF_VMM_CALL_HOST && pVCpu->vmm.s.enmCallRing3Operation == VMMCALLRING3_VMM_LOGGER_FLUSH));
return rc;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GCFGM_SET_VALUE:
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
int rc;
return rc;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
case VMMR0_DO_INTNET_OPEN:
return VERR_INVALID_PARAMETER;
case VMMR0_DO_INTNET_IF_CLOSE:
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFCLOSEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFGETBUFFERPTRSREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETMACADDRESSREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETACTIVEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_INTNET_IF_SEND:
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSENDREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_INTNET_IF_WAIT:
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFWAITREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFWAITREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
#ifdef VBOX_WITH_PCI_PASSTHROUGH
case VMMR0_DO_PCIRAW_REQ:
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PPCIRAWSENDREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_NOP:
case VMMR0_DO_SLOW_NOP:
return VINF_SUCCESS;
case VMMR0_DO_TESTS:
return VINF_SUCCESS;
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
return VERR_INVALID_CPU_ID;
return VERR_NOT_SUPPORTED;
typedef struct VMMR0ENTRYEXARGS
VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)
switch (enmOperation)
case VMMR0_DO_GMM_FREE_PAGES:
case VMMR0_DO_VMMR0_INIT:
case VMMR0_DO_VMMR0_TERM:
#ifdef RT_ARCH_X86
#ifdef LOG_ENABLED
# 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);