VMMR0.cpp revision 1d2d38b5af44dca06849ba586f29753c3c982072
77b1a2d8b5dbe2c0b5200794914239fee3c8ee5dvboxsync/* $Id$ */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** @file
77b1a2d8b5dbe2c0b5200794914239fee3c8ee5dvboxsync * VMM - Host Context Ring 0.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync *
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 *
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
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Header Files *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#define LOG_GROUP LOG_GROUP_VMM
662d52947eeb3fc8fca3b23991a5eee47077f896vboxsync#include <VBox/vmm.h>
da957c069c2a3c582fe265ff88170ce4c42b499dvboxsync#include <VBox/sup.h>
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#include <VBox/trpm.h>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#include <VBox/cpum.h>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#include <VBox/stam.h>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#include <VBox/tm.h>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#include "VMMInternal.h"
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#include <VBox/vm.h>
9496f2d398b49813176939d7a339ae513d5175efvboxsync#include <VBox/gvmm.h>
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#include <VBox/gmm.h>
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#include <VBox/intnet.h>
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#include <VBox/hwaccm.h>
efff36b306e370346025647a158689021df2e1d1vboxsync#include <VBox/param.h>
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync#include <VBox/err.h>
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#include <VBox/version.h>
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#include <VBox/log.h>
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#include <iprt/assert.h>
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync#include <iprt/stdarg.h>
efff36b306e370346025647a158689021df2e1d1vboxsync#include <iprt/mp.h>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#include <iprt/string.h>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#if defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */
efff36b306e370346025647a158689021df2e1d1vboxsync# pragma intrinsic(_AddressOfReturnAddress)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#endif
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
efff36b306e370346025647a158689021df2e1d1vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Internal Functions *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic int VMMR0Init(PVM pVM, uint32_t uSvnRev);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic int VMMR0Term(PVM pVM);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync__BEGIN_DECLS
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncVMMR0DECL(int) ModuleInit(void);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncVMMR0DECL(void) ModuleTerm(void);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync__END_DECLS
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Global Variables *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** Pointer to the internal networking service instance. */
0abd77741a608f6c41c8dfcd4781b8b84adf1044vboxsyncPINTNET g_pIntNet = 0;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#endif
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/**
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Initialize the module.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * This is called when we're first loaded.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync *
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @returns 0 on success.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @returns VBox status on failure.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsyncVMMR0DECL(int) ModuleInit(void)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync{
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogFlow(("ModuleInit:\n"));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /*
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Initialize the GVMM, GMM.& HWACCM
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync int rc = GVMMR0Init();
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync if (RT_SUCCESS(rc))
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync rc = GMMR0Init();
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (RT_SUCCESS(rc))
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync rc = HWACCMR0Init();
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (RT_SUCCESS(rc))
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("ModuleInit: g_pIntNet=%p\n", g_pIntNet));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync g_pIntNet = NULL;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("ModuleInit: g_pIntNet=%p should be NULL now...\n", g_pIntNet));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync rc = INTNETR0Create(&g_pIntNet);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (VBOX_SUCCESS(rc))
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("ModuleInit: returns success. g_pIntNet=%p\n", g_pIntNet));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return VINF_SUCCESS;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync g_pIntNet = NULL;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync LogFlow(("ModuleTerm: returns %Vrc\n", rc));
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#else
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync LogFlow(("ModuleInit: returns success.\n"));
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync return VINF_SUCCESS;
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#endif
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync }
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync }
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync LogFlow(("ModuleInit: failed %Rrc\n", rc));
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return rc;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync}
9496f2d398b49813176939d7a339ae513d5175efvboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/**
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Terminate the module.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * This is called when we're finally unloaded.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsyncVMMR0DECL(void) ModuleTerm(void)
21029597fc4b76d0db0c9542daee201447281781vboxsync{
21029597fc4b76d0db0c9542daee201447281781vboxsync LogFlow(("ModuleTerm:\n"));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
9496f2d398b49813176939d7a339ae513d5175efvboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Destroy the internal networking instance.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync if (g_pIntNet)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync INTNETR0Destroy(g_pIntNet);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync g_pIntNet = NULL;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
9496f2d398b49813176939d7a339ae513d5175efvboxsync#endif
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* Global HWACCM cleanup */
9496f2d398b49813176939d7a339ae513d5175efvboxsync HWACCMR0Term();
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Destroy the GMM and GVMM instances.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync GMMR0Term();
9496f2d398b49813176939d7a339ae513d5175efvboxsync GVMMR0Term();
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync LogFlow(("ModuleTerm: returns\n"));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync}
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/**
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Initaties the R0 driver for a particular VM instance.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync *
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * @returns VBox status code.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pVM The VM instance in question.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @param uSvnRev The SVN revision of the ring-3 part.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @thread EMT.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsyncstatic int VMMR0Init(PVM pVM, uint32_t uSvnRev)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync{
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /*
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Match the SVN revisions.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync if (uSvnRev != VMMGetSvnRev())
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync return VERR_VERSION_MISMATCH;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync if ( !VALID_PTR(pVM)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync || pVM->pVMR0 != pVM)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync return VERR_INVALID_PARAMETER;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /*
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Register the EMT R0 logger instance.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync PVMMR0LOGGER pR0Logger = pVM->vmm.s.pR0Logger;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync if (pR0Logger)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync {
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
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: after %p reg\n", RTLogDefaultInstance()));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync RTLogSetDefaultInstanceThread(NULL, 0);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: after %p dereg\n", RTLogDefaultInstance()));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync LogCom(("VMMR0Init: returned succesfully from direct logger call.\n"));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync pR0Logger->Logger.pfnFlush(&pR0Logger->Logger);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogCom(("VMMR0Init: returned succesfully from direct flush call.\n"));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
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 RTLogSetDefaultInstanceThread(NULL, 0);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogCom(("VMMR0Init: after %p dereg2\n", RTLogDefaultInstance()));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
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
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#endif
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 }
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Initialize the per VM data for GVMM and GMM.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync int rc = GVMMR0InitVM(pVM);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync// if (RT_SUCCESS(rc))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync// rc = GMMR0InitPerVMData(pVM);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (RT_SUCCESS(rc))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync {
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Init HWACCM.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync rc = HWACCMR0InitVM(pVM);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (RT_SUCCESS(rc))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync {
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Init CPUM.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync rc = CPUMR0Init(pVM);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (RT_SUCCESS(rc))
a9d49c8f2b28a72e6a4db86eee91e4569290157bvboxsync return rc;
a9d49c8f2b28a72e6a4db86eee91e4569290157bvboxsync }
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync }
a9d49c8f2b28a72e6a4db86eee91e4569290157bvboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* failed */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync RTLogSetDefaultInstanceThread(NULL, 0);
9496f2d398b49813176939d7a339ae513d5175efvboxsync return rc;
9496f2d398b49813176939d7a339ae513d5175efvboxsync}
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync/**
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync * Terminates the R0 driver for a particular VM instance.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync *
9496f2d398b49813176939d7a339ae513d5175efvboxsync * @returns VBox status code.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync *
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param pVM The VM instance in question.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * @thread EMT.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncstatic int VMMR0Term(PVM pVM)
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync{
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync HWACCMR0TermVM(pVM);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Deregister the logger.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync */
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync RTLogSetDefaultInstanceThread(NULL, 0);
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync return VINF_SUCCESS;
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync}
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync/**
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * Calls the ring-3 host code.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync *
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.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync */
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsyncVMMR0DECL(int) VMMR0CallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync{
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** @todo profile this! */
9496f2d398b49813176939d7a339ae513d5175efvboxsync pVM->vmm.s.enmCallHostOperation = enmOperation;
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync pVM->vmm.s.u64CallHostArg = uArg;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync pVM->vmm.s.rcCallHost = VERR_INTERNAL_ERROR;
9496f2d398b49813176939d7a339ae513d5175efvboxsync int rc = vmmR0CallHostLongJmp(&pVM->vmm.s.CallHostR0JmpBuf, VINF_VMM_CALL_HOST);
9496f2d398b49813176939d7a339ae513d5175efvboxsync if (rc == VINF_SUCCESS)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync rc = pVM->vmm.s.rcCallHost;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return rc;
9496f2d398b49813176939d7a339ae513d5175efvboxsync}
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#ifdef VBOX_WITH_STATISTICS
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync/**
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Record return code statistics
ffbe6daf773e38167f3cabaf1f063d84ecd063e9vboxsync * @param pVM The VM handle.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param rc The status code.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncstatic void vmmR0RecordRC(PVM pVM, int rc)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync{
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Collect statistics.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync */
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync switch (rc)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_SUCCESS:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetNormal);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_INTERRUPT:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterrupt);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_INTERRUPT_HYPER:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterruptHyper);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_GUEST_TRAP:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetGuestTrap);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_RING_SWITCH:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRingSwitch);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_RING_SWITCH_INT:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRingSwitchInt);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_EM_RAW_EXCEPTION_PRIVILEGED:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetExceptionPrivilege);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_EM_RAW_STALE_SELECTOR:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetStaleSelector);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_EM_RAW_IRET_TRAP:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIRETTrap);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_IOM_HC_IOPORT_READ:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIORead);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_IOM_HC_IOPORT_WRITE:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIOWrite);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_IOM_HC_MMIO_READ:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIORead);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_IOM_HC_MMIO_WRITE:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOWrite);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_IOM_HC_MMIO_READ_WRITE:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOReadWrite);
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync break;
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync case VINF_PATM_HC_MMIO_PATCH_READ:
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOPatchRead);
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync break;
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync case VINF_PATM_HC_MMIO_PATCH_WRITE:
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOPatchWrite);
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync break;
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync case VINF_EM_RAW_EMULATE_INSTR:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetEmulate);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_PATCH_EMULATE_INSTR:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchEmulate);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetLDTFault);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetGDTFault);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIDTFault);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetTSSFault);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_EMULATE_INSTR_PD_FAULT:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDFault);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_CSAM_PENDING_ACTION:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetCSAMTask);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_PGM_SYNC_CR3:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetSyncCR3);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_PATM_PATCH_INT3:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchInt3);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_PATM_PATCH_TRAP_PF:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchPF);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_PATM_PATCH_TRAP_GP:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchGP);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_PATM_PENDING_IRQ_AFTER_IRET:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchIretIRQ);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VERR_REM_FLUSHED_PAGES_OVERFLOW:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPageOverflow);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RESCHEDULE_REM:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRescheduleREM);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_TO_R3:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetToR3);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_TIMER_PENDING:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetTimerPending);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_RAW_INTERRUPT_PENDING:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterruptPending);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_VMM_CALL_HOST:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync switch (pVM->vmm.s.enmCallHostOperation)
9496f2d398b49813176939d7a339ae513d5175efvboxsync {
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VMMCALLHOST_PDM_LOCK:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDMLock);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_PDM_QUEUE_FLUSH:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDMQueueFlush);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_PGM_POOL_GROW:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMPoolGrow);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_PGM_LOCK:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMLock);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRemReplay);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_PGM_RAM_GROW_RANGE:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMGrowRAM);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_VMM_LOGGER_FLUSH:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetLogFlush);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_VM_SET_ERROR:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetVMSetError);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_VM_SET_RUNTIME_ERROR:
9496f2d398b49813176939d7a339ae513d5175efvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetVMSetRuntimeError);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VMMCALLHOST_VM_R0_HYPER_ASSERTION:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetHyperAssertion);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync default:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetCallHost);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync }
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_PATM_DUPLICATE_FUNCTION:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPATMDuplicateFn);
9496f2d398b49813176939d7a339ae513d5175efvboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_PGM_CHANGE_MODE:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMChangeMode);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VINF_EM_RAW_EMULATE_INSTR_HLT:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetEmulHlt);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync case VINF_EM_PENDING_REQUEST:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPendingRequest);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync default:
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMisc);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync break;
9496f2d398b49813176939d7a339ae513d5175efvboxsync }
9496f2d398b49813176939d7a339ae513d5175efvboxsync}
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync#endif /* VBOX_WITH_STATISTICS */
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync/**
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * The Ring 0 entry point, called by the interrupt gate.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync *
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.
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync */
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsyncVMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg)
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync{
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync switch (enmOperation)
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync {
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync#ifdef VBOX_WITH_IDT_PATCHING
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync /*
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync * Switch to GC.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * These calls return whatever the GC returns.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync */
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync case VMMR0_DO_RAW_RUN:
efff36b306e370346025647a158689021df2e1d1vboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Safety precaution as VMX disables the switcher. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (pVM->vmm.s.fSwitcherDisabled)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return VERR_NOT_SUPPORTED;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync register int rc;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pVM->vmm.s.iLastGCRc = rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#ifdef VBOX_WITH_STATISTICS
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync vmmR0RecordRC(pVM, rc);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#endif
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
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 */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if ( rc == VINF_EM_RAW_INTERRUPT
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync || rc == VINF_EM_RAW_INTERRUPT_HYPER)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
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 */
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# elif defined(RT_ARCH_X86)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync void *pvRet = (uint8_t *)&pVM - sizeof(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync# else
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync# error "huh?"
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync# endif
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if ( ((uintptr_t *)pvRet)[1] == (uintptr_t)pVM
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync && ((uintptr_t *)pvRet)[2] == (uintptr_t)enmOperation
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync && ((uintptr_t *)pvRet)[3] == (uintptr_t)pvArg)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync TRPMR0SetupInterruptDispatcherFrame(pVM, pvRet);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync else
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync# if defined(DEBUG) || defined(LOG_ENABLED)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync static bool s_fHaveWarned = false;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (!s_fHaveWarned)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync s_fHaveWarned = true;
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 }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync# endif
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync TRPMR0DispatchHostInterrupt(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
7b067f3f07310bff46d1d6a4ac94d8b9bb7ccccdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return rc;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Switch to GC to execute Hypervisor function.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync case VMMR0_DO_CALL_HYPERVISOR:
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Safety precaution as VMX disables the switcher. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (pVM->vmm.s.fSwitcherDisabled)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return VERR_NOT_SUPPORTED;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /** @todo dispatch interrupts? */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync ASMSetFlags(fFlags);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return rc;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * For profiling.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync case VMMR0_DO_NOP:
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return VINF_SUCCESS;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#endif /* VBOX_WITH_IDT_PATCHING */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync default:
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
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 */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Log(("operation %#x is not supported\n", enmOperation));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return VERR_NOT_SUPPORTED;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync}
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/**
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * The Ring 0 entry point, called by the fast-ioctl path.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync *
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_.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncVMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMMR0OPERATION enmOperation)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync{
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync switch (enmOperation)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Switch to GC and run guest raw mode code.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Disable interrupts before doing the world switch.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync case VMMR0_DO_RAW_RUN:
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Safety precaution as hwaccm disables the switcher. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (RT_LIKELY(!pVM->vmm.s.fSwitcherDisabled))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync RTCCUINTREG uFlags = ASMIntDisableFlags();
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync TMNotifyStartOfExecution(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pVM->vmm.s.iLastGCRc = rc;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync TMNotifyEndOfExecution(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if ( rc == VINF_EM_RAW_INTERRUPT
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync || rc == VINF_EM_RAW_INTERRUPT_HYPER)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync TRPMR0DispatchHostInterrupt(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync ASMSetFlags(uFlags);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#ifdef VBOX_WITH_STATISTICS
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync vmmR0RecordRC(pVM, rc);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#endif
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync else
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pVM->vmm.s.iLastGCRc = VERR_NOT_SUPPORTED;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync break;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Run guest code using the available hardware acceleration technology.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync *
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 */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync case VMMR0_DO_HWACC_RUN:
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#ifndef RT_OS_WINDOWS /** @todo check other hosts */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync RTCCUINTREG uFlags = ASMIntDisableFlags();
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#endif
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = HWACCMR0Enter(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (VBOX_SUCCESS(rc))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
efff36b306e370346025647a158689021df2e1d1vboxsync rc = vmmR0CallHostSetJmp(&pVM->vmm.s.CallHostR0JmpBuf, HWACCMR0RunGuestCode, pVM); /* this may resume code. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc2 = HWACCMR0Leave(pVM);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync AssertRC(rc2);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pVM->vmm.s.iLastGCRc = rc;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#ifndef RT_OS_WINDOWS /** @todo check other hosts */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync ASMSetFlags(uFlags);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#endif
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync#ifdef VBOX_WITH_STATISTICS
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync vmmR0RecordRC(pVM, rc);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#endif
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* No special action required for external interrupts, just return. */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync break;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync }
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync
ff88d4153cd65650577e8c2d1a5a3fdfa0404a80vboxsync /*
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * For profiling.
fe813b3594039ba864493438e78ee0e7132bc445vboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_NOP:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pVM->vmm.s.iLastGCRc = VINF_SUCCESS;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync break;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync /*
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * Impossible.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync default:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync AssertMsgFailed(("%#x\n", enmOperation));
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pVM->vmm.s.iLastGCRc = VERR_NOT_SUPPORTED;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync break;
ff88d4153cd65650577e8c2d1a5a3fdfa0404a80vboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync}
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
fe813b3594039ba864493438e78ee0e7132bc445vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/**
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Validates a session or VM session argument.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @returns true / false accordingly.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param pVM The VM argument.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pSession The session argument.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsyncDECLINLINE(bool) vmmR0IsValidSession(PVM pVM, PSUPDRVSESSION pClaimedSession, PSUPDRVSESSION pSession)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync{
fe813b3594039ba864493438e78ee0e7132bc445vboxsync /* This must be set! */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (!pSession)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return false;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Only one out of the two. */
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync if (pVM && pClaimedSession)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return false;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (pVM)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync pClaimedSession = pVM->pSession;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return pClaimedSession == pSession;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync}
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/**
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * VMMR0EntryEx worker function, either called directly or when ever possible
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * called thru a longjmp so we can exit safely on failure.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync *
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_.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync */
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsyncstatic int vmmR0EntryExWorker(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync{
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /*
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Common VM pointer validation.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync */
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync if (pVM)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (RT_UNLIKELY( !VALID_PTR(pVM)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync || ((uintptr_t)pVM & PAGE_OFFSET_MASK)))
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {
fe813b3594039ba864493438e78ee0e7132bc445vboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p! (op=%d)\n", pVM, enmOperation);
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return VERR_INVALID_POINTER;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (RT_UNLIKELY( pVM->enmVMState < VMSTATE_CREATING
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync || pVM->enmVMState > VMSTATE_TERMINATED
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync || pVM->pVMR0 != pVM))
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync {
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p:{enmVMState=%d, .pVMR0=%p}! (op=%d)\n",
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pVM, pVM->enmVMState, pVM->pVMR0, enmOperation);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return VERR_INVALID_POINTER;
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync }
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync }
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
594521f7faf13f7a88f31e6cd76629bd67340229vboxsync switch (enmOperation)
e04eeee1b306d610b0441cee9bf1c750100254d5vboxsync {
fe813b3594039ba864493438e78ee0e7132bc445vboxsync /*
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * GVM requests
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_GVMM_CREATE_VM:
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync if (pVM || u64Arg)
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return VERR_INVALID_PARAMETER;
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_GVMM_DESTROY_VM:
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync if (pReqHdr || u64Arg)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return VERR_INVALID_PARAMETER;
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync return GVMMR0DestroyVM(pVM);
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync case VMMR0_DO_GVMM_SCHED_HALT:
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync if (pReqHdr)
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return VERR_INVALID_PARAMETER;
fe813b3594039ba864493438e78ee0e7132bc445vboxsync return GVMMR0SchedHalt(pVM, u64Arg);
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_GVMM_SCHED_WAKE_UP:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (pReqHdr || u64Arg)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return VERR_INVALID_PARAMETER;
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return GVMMR0SchedWakeUp(pVM);
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync case VMMR0_DO_GVMM_SCHED_POLL:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (pReqHdr || u64Arg > 1)
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return VERR_INVALID_PARAMETER;
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return GVMMR0SchedPoll(pVM, !!u64Arg);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync case VMMR0_DO_GVMM_QUERY_STATISTICS:
594521f7faf13f7a88f31e6cd76629bd67340229vboxsync if (u64Arg)
e04eeee1b306d610b0441cee9bf1c750100254d5vboxsync return VERR_INVALID_PARAMETER;
fe813b3594039ba864493438e78ee0e7132bc445vboxsync return GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_GVMM_RESET_STATISTICS:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (u64Arg)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return VERR_INVALID_PARAMETER;
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync return GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /*
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Initialize the R0 part of a VM instance.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync */
af90f37ee9175da3aed36bda13519a917cc4effbvboxsync case VMMR0_DO_VMMR0_INIT:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return VMMR0Init(pVM, (uint32_t)u64Arg);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Terminate the R0 part of a VM instance.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VMMR0_DO_VMMR0_TERM:
9496f2d398b49813176939d7a339ae513d5175efvboxsync return VMMR0Term(pVM);
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Attempt to enable hwacc mode and check the current setting.
9496f2d398b49813176939d7a339ae513d5175efvboxsync *
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VMMR0_DO_HWACC_ENABLE:
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return HWACCMR0EnableAllCpus(pVM, (HWACCMSTATE)u64Arg);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
fe813b3594039ba864493438e78ee0e7132bc445vboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Setup the hardware accelerated raw-mode session.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VMMR0_DO_HWACC_SETUP_VM:
9496f2d398b49813176939d7a339ae513d5175efvboxsync {
9496f2d398b49813176939d7a339ae513d5175efvboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
9496f2d398b49813176939d7a339ae513d5175efvboxsync int rc = HWACCMR0SetupVM(pVM);
9496f2d398b49813176939d7a339ae513d5175efvboxsync ASMSetFlags(fFlags);
9496f2d398b49813176939d7a339ae513d5175efvboxsync return rc;
9496f2d398b49813176939d7a339ae513d5175efvboxsync }
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync /*
fe813b3594039ba864493438e78ee0e7132bc445vboxsync * Switch to GC to execute Hypervisor function.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VMMR0_DO_CALL_HYPERVISOR:
9496f2d398b49813176939d7a339ae513d5175efvboxsync {
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* Safety precaution as HWACCM can disable the switcher. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
9496f2d398b49813176939d7a339ae513d5175efvboxsync if (RT_UNLIKELY(pVM->vmm.s.fSwitcherDisabled))
9496f2d398b49813176939d7a339ae513d5175efvboxsync return VERR_NOT_SUPPORTED;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync int rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** @todo dispatch interrupts? */
9496f2d398b49813176939d7a339ae513d5175efvboxsync ASMSetFlags(fFlags);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return rc;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /*
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * PGM wrappers.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync case VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES:
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync return PGMR0PhysAllocateHandyPages(pVM);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync /*
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * GMM wrappers.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync case VMMR0_DO_GMM_INITIAL_RESERVATION:
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync if (u64Arg)
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync return VERR_INVALID_PARAMETER;
da3503c04ce76e653401396fe2795a9bc2427a1dvboxsync return GMMR0InitialReservationReq(pVM, (PGMMINITIALRESERVATIONREQ)pReqHdr);
da3503c04ce76e653401396fe2795a9bc2427a1dvboxsync case VMMR0_DO_GMM_UPDATE_RESERVATION:
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync if (u64Arg)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return VERR_INVALID_PARAMETER;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return GMMR0UpdateReservationReq(pVM, (PGMMUPDATERESERVATIONREQ)pReqHdr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_GMM_ALLOCATE_PAGES:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0AllocatePagesReq(pVM, (PGMMALLOCATEPAGESREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_GMM_FREE_PAGES:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0FreePagesReq(pVM, (PGMMFREEPAGESREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_GMM_BALLOONED_PAGES:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0BalloonedPagesReq(pVM, (PGMMBALLOONEDPAGESREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_GMM_DEFLATED_BALLOON:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (pReqHdr)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0DeflatedBalloon(pVM, (uint32_t)u64Arg);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_GMM_MAP_UNMAP_CHUNK:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0MapUnmapChunkReq(pVM, (PGMMMAPUNMAPCHUNKREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_GMM_SEED_CHUNK:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (pReqHdr)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return GMMR0SeedChunk(pVM, (RTR3PTR)u64Arg);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * A quick GCFGM mock-up.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /** @todo GCFGM with proper access control, ring-3 management interface and all that. */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_GCFGM_SET_VALUE:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_GCFGM_QUERY_VALUE:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (pVM || !pReqHdr || u64Arg)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return VERR_INVALID_PARAMETER;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync PGCFGMVALUEREQ pReq = (PGCFGMVALUEREQ)pReqHdr;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (pReq->Hdr.cbReq != sizeof(*pReq))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync int rc;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (enmOperation == VMMR0_DO_GCFGM_SET_VALUE)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync {
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 }
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync else
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync {
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 }
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return rc;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync }
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Requests to the internal networking service.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_INTNET_OPEN:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync {
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync PINTNETOPENREQ pReq = (PINTNETOPENREQ)pReqHdr;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReq || !vmmR0IsValidSession(pVM, pReq->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!g_pIntNet)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_NOT_SUPPORTED;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0OpenReq(g_pIntNet, pSession, pReq);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync }
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_INTNET_IF_CLOSE:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFCLOSEREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!g_pIntNet)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_NOT_SUPPORTED;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfCloseReq(g_pIntNet, pSession, (PINTNETIFCLOSEREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_INTNET_IF_GET_RING3_BUFFER:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFGETRING3BUFFERREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!g_pIntNet)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_NOT_SUPPORTED;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfGetRing3BufferReq(g_pIntNet, pSession, (PINTNETIFGETRING3BUFFERREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!g_pIntNet)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_NOT_SUPPORTED;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfSetPromiscuousModeReq(g_pIntNet, pSession, (PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETMACADDRESSREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!g_pIntNet)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_NOT_SUPPORTED;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfSetMacAddressReq(g_pIntNet, pSession, (PINTNETIFSETMACADDRESSREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_INTNET_IF_SET_ACTIVE:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETACTIVEREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!g_pIntNet)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_NOT_SUPPORTED;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfSetActiveReq(g_pIntNet, pSession, (PINTNETIFSETACTIVEREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_INTNET_IF_SEND:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSENDREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!g_pIntNet)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_NOT_SUPPORTED;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfSendReq(g_pIntNet, pSession, (PINTNETIFSENDREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_INTNET_IF_WAIT:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFWAITREQ)pReqHdr)->pSession, pSession))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_INVALID_PARAMETER;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!g_pIntNet)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VERR_NOT_SUPPORTED;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return INTNETR0IfWaitReq(g_pIntNet, pSession, (PINTNETIFWAITREQ)pReqHdr);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync#endif /* VBOX_WITH_INTERNAL_NETWORKING */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * For profiling.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_NOP:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_SLOW_NOP:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VINF_SUCCESS;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * For testing Ring-0 APIs invoked in this environment.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case VMMR0_DO_TESTS:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /** @todo make new test */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VINF_SUCCESS;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync default:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /*
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.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync Log(("operation %#x is not supported\n", enmOperation));
cba6719bd64ec749967bbe931230452664109857vboxsync return VERR_NOT_SUPPORTED;
cba6719bd64ec749967bbe931230452664109857vboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync}
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/**
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync * Argument for vmmR0EntryExWrapper containing the argument s ofr VMMR0EntryEx.
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsynctypedef struct VMMR0ENTRYEXARGS
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync{
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync PVM pVM;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync VMMR0OPERATION enmOperation;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync PSUPVMMR0REQHDR pReq;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync uint64_t u64Arg;
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync PSUPDRVSESSION pSession;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync} VMMR0ENTRYEXARGS;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync/** Pointer to a vmmR0EntryExWrapper argument package. */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsynctypedef VMMR0ENTRYEXARGS *PVMMR0ENTRYEXARGS;
090d729e786b999dc285f8ea267f9effd1319544vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/**
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * This is just a longjmp wrapper function for VMMR0EntryEx calls.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync *
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @returns VBox status code.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @param pvArgs The argument package
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsyncstatic int vmmR0EntryExWrapper(void *pvArgs)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync{
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM,
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync ((PVMMR0ENTRYEXARGS)pvArgs)->enmOperation,
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync ((PVMMR0ENTRYEXARGS)pvArgs)->pReq,
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync ((PVMMR0ENTRYEXARGS)pvArgs)->u64Arg,
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync ((PVMMR0ENTRYEXARGS)pvArgs)->pSession);
9496f2d398b49813176939d7a339ae513d5175efvboxsync}
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/**
9496f2d398b49813176939d7a339ae513d5175efvboxsync * The Ring 0 entry point, called by the support library (SUP).
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync *
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_.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsyncVMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)
9496f2d398b49813176939d7a339ae513d5175efvboxsync{
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /*
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Requests that should only happen on the EMT thread will be
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * wrapped in a setjmp so we can assert without causing trouble.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync */
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync if ( VALID_PTR(pVM)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync && pVM->pVMR0)
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync {
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync switch (enmOperation)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync {
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync case VMMR0_DO_VMMR0_INIT:
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync case VMMR0_DO_VMMR0_TERM:
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VMMR0_DO_GMM_INITIAL_RESERVATION:
da3503c04ce76e653401396fe2795a9bc2427a1dvboxsync case VMMR0_DO_GMM_UPDATE_RESERVATION:
9496f2d398b49813176939d7a339ae513d5175efvboxsync case VMMR0_DO_GMM_ALLOCATE_PAGES:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_GMM_FREE_PAGES:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_GMM_BALLOONED_PAGES:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_GMM_DEFLATED_BALLOON:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case VMMR0_DO_GMM_MAP_UNMAP_CHUNK:
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync case VMMR0_DO_GMM_SEED_CHUNK:
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync {
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** @todo validate this EMT claim... GVM knows. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync VMMR0ENTRYEXARGS Args;
090d729e786b999dc285f8ea267f9effd1319544vboxsync Args.pVM = pVM;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync Args.enmOperation = enmOperation;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync Args.pReq = pReq;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync Args.u64Arg = u64Arg;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync Args.pSession = pSession;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return vmmR0CallHostSetJmpEx(&pVM->vmm.s.CallHostR0JmpBuf, vmmR0EntryExWrapper, &Args);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync }
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync default:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync break;
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync }
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync }
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync return vmmR0EntryExWorker(pVM, enmOperation, pReq, u64Arg, pSession);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync}
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync/**
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync * Internal R0 logger worker: Flush logger.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pLogger The logger instance to flush.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @remark This function must be exported!
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncVMMR0DECL(void) vmmR0LoggerFlush(PRTLOGGER pLogger)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync{
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /*
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Convert the pLogger into a VM handle and 'call' back to Ring-3.
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync * (This is a bit paranoid code.)
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync */
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync PVMMR0LOGGER pR0Logger = (PVMMR0LOGGER)((uintptr_t)pLogger - RT_OFFSETOF(VMMR0LOGGER, Logger));
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync if ( !VALID_PTR(pR0Logger)
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync || !VALID_PTR(pR0Logger + 1)
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync || !VALID_PTR(pLogger)
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync || pLogger->u32Magic != RTLOGGER_MAGIC)
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync {
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync#ifdef DEBUG
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync SUPR0Printf("vmmR0LoggerFlush: pLogger=%p!\n", pLogger);
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync#endif
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync return;
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync }
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync PVM pVM = pR0Logger->pVM;
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync if ( !VALID_PTR(pVM)
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync || pVM->pVMR0 != pVM)
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync {
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync#ifdef DEBUG
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync SUPR0Printf("vmmR0LoggerFlush: pVM=%p! pVMR0=%p! pLogger=%p\n", pVM, pVM->pVMR0, pLogger);
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync#endif
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync return;
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync }
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync /*
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync * Check that the jump buffer is armed.
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync */
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync#ifdef RT_ARCH_X86
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync if (!pVM->vmm.s.CallHostR0JmpBuf.eip)
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync#else
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync if (!pVM->vmm.s.CallHostR0JmpBuf.rip)
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync#endif
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync {
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync#ifdef DEBUG
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync SUPR0Printf("vmmR0LoggerFlush: Jump buffer isn't armed!\n");
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync#endif
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync pLogger->offScratch = 0;
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync return;
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync }
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync VMMR0CallHost(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync}
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync/**
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync * Jump back to ring-3 if we're the EMT and the longjmp is armed.
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync *
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.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncDECLEXPORT(bool) RTCALL RTAssertDoBreakpoint(void)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync{
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync PVM pVM = GVMMR0GetVMByEMT(NIL_RTNATIVETHREAD);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (pVM)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#ifdef RT_ARCH_X86
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (pVM->vmm.s.CallHostR0JmpBuf.eip)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#else
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync if (pVM->vmm.s.CallHostR0JmpBuf.rip)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#endif
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return RT_FAILURE_NP(rc);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#ifdef RT_OS_LINUX
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return true;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#else
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return false;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#endif
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync}
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/**
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Override this so we can push it up to ring-3.
efff36b306e370346025647a158689021df2e1d1vboxsync *
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.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncDECLEXPORT(void) RTCALL AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync{
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#ifndef DEBUG_sandervl
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync SUPR0Printf("\n!!R0-Assertion Failed!!\n"
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync "Expression: %s\n"
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync "Location : %s(%d) %s\n",
efff36b306e370346025647a158689021df2e1d1vboxsync pszExpr, pszFile, uLine, pszFunction);
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync#endif
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync LogAlways(("\n!!R0-Assertion Failed!!\n"
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync "Expression: %s\n"
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync "Location : %s(%d) %s\n",
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync pszExpr, pszFile, uLine, pszFunction));
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync PVM pVM = GVMMR0GetVMByEMT(NIL_RTNATIVETHREAD);
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync if (pVM)
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 pszExpr, pszFile, uLine, pszFunction);
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync}
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync/**
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync * Callback for RTLogFormatV which writes to the ring-3 log port.
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync * See PFNLOGOUTPUT() for details.
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync */
27b178e99b06a68ef52353b15bc647674d2006bcvboxsyncstatic DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars)
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync{
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync for (size_t i = 0; i < cbChars; i++)
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync {
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync#ifndef DEBUG_sandervl
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync SUPR0Printf("%c", pachChars[i]);
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync#endif
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync LogAlways(("%c", pachChars[i]));
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync }
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync return cbChars;
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync}
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync
a3369a746b56a8966dd78619f4d191c9662f400dvboxsyncDECLEXPORT(void) RTCALL AssertMsg2(const char *pszFormat, ...)
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync{
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync PRTLOGGER pLog = RTLogDefaultInstance(); /** @todo we want this for release as well! */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (pLog)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync va_list args;
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync va_start(args, pszFormat);
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync RTLogFormatV(rtLogOutput, pLog, pszFormat, args);
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync PVM pVM = GVMMR0GetVMByEMT(NIL_RTNATIVETHREAD);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (pVM)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync RTStrPrintfV(pVM->vmm.s.szRing0AssertMsg2, sizeof(pVM->vmm.s.szRing0AssertMsg2), pszFormat, args);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync va_end(args);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync }
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync}
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync