VMMR0.cpp revision d760a8145d329c88cdeb46ccf2489061bae288f0
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/* $Id$ */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/** @file
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * VMM - Host Context Ring 0.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Copyright (C) 2006-2007 innotek GmbH
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * available from http://www.virtualbox.org. This file is free software;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * you can redistribute it and/or modify it under the terms of the GNU
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * General Public License as published by the Free Software Foundation,
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/*******************************************************************************
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync* Header Files *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync*******************************************************************************/
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#define LOG_GROUP LOG_GROUP_VMM
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/vmm.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/sup.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/trpm.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/cpum.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/stam.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/tm.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include "VMMInternal.h"
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/vm.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/gvmm.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/gmm.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/intnet.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/hwaccm.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/param.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/err.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/version.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <VBox/log.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <iprt/assert.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#include <iprt/stdarg.h>
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#if defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync# pragma intrinsic(_AddressOfReturnAddress)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/*******************************************************************************
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync* Internal Functions *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync*******************************************************************************/
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncstatic int VMMR0Init(PVM pVM, unsigned uVersion);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncstatic int VMMR0Term(PVM pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync__BEGIN_DECLS
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncVMMR0DECL(int) ModuleInit(void);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncVMMR0DECL(void) ModuleTerm(void);
dbec828311ed2a5cf6fbc68fe4391d516ba4f92fvboxsync__END_DECLS
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/*******************************************************************************
5eb36887f6970e0033f63fa135f3bb8fbfd6059bvboxsync* Global Variables *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync*******************************************************************************/
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/** Pointer to the internal networking service instance. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncPINTNET g_pIntNet = 0;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Initialize the module.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * This is called when we're first loaded.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns 0 on success.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns VBox status on failure.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncVMMR0DECL(int) ModuleInit(void)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleInit:\n"));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Initialize the GVMM.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = GVMMR0Init();
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (RT_SUCCESS(rc))
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleInit: g_pIntNet=%p\n", g_pIntNet));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync g_pIntNet = NULL;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleInit: g_pIntNet=%p should be NULL now...\n", g_pIntNet));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = INTNETR0Create(&g_pIntNet);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (VBOX_SUCCESS(rc))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleInit: returns success. g_pIntNet=%p\n", g_pIntNet));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VINF_SUCCESS;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync g_pIntNet = NULL;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleTerm: returns %Vrc\n", rc));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#else
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleInit: returns success.\n"));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VINF_SUCCESS;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleInit: failed %Vrc\n", rc));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Terminate the module.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * This is called when we're finally unloaded.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncVMMR0DECL(void) ModuleTerm(void)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleTerm:\n"));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Destroy the internal networking instance.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (g_pIntNet)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync INTNETR0Destroy(g_pIntNet);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync g_pIntNet = NULL;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Destroy the GVMM instance.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync GVMMR0Term();
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("ModuleTerm: returns\n"));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Initaties the R0 driver for a particular VM instance.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns VBox status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pVM The VM instance in question.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param uVersion The minimum module version required.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @thread EMT.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncstatic int VMMR0Init(PVM pVM, unsigned uVersion)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Check if compatible version.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if ( uVersion != VBOX_VERSION
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync && ( VBOX_GET_VERSION_MAJOR(uVersion) != VBOX_VERSION_MAJOR
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || VBOX_GET_VERSION_MINOR(uVersion) < VBOX_VERSION_MINOR))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_VERSION_MISMATCH;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if ( !VALID_PTR(pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || pVM->pVMR0 != pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Register the EMT R0 logger instance.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync PVMMR0LOGGER pR0Logger = pVM->vmm.s.pR0Logger;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pR0Logger)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#if 0 /* testing of the logger. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: before %p\n", RTLogDefaultInstance()));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: pfnFlush=%p actual=%p\n", pR0Logger->Logger.pfnFlush, vmmR0LoggerFlush));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: pfnLogger=%p actual=%p\n", pR0Logger->Logger.pfnLogger, vmmR0LoggerWrapper));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: offScratch=%d fFlags=%#x fDestFlags=%#x\n", pR0Logger->Logger.offScratch, pR0Logger->Logger.fFlags, pR0Logger->Logger.fDestFlags));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: after %p reg\n", RTLogDefaultInstance()));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogSetDefaultInstanceThread(NULL, 0);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: after %p dereg\n", RTLogDefaultInstance()));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: returned succesfully from direct logger call.\n"));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pR0Logger->Logger.pfnFlush(&pR0Logger->Logger);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: returned succesfully from direct flush call.\n"));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: after %p reg2\n", RTLogDefaultInstance()));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: returned succesfully from direct logger call (2). offScratch=%d\n", pR0Logger->Logger.offScratch));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogSetDefaultInstanceThread(NULL, 0);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: after %p dereg2\n", RTLogDefaultInstance()));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogLoggerEx(&pR0Logger->Logger, 0, ~0U, "hello ring-0 logger (RTLogLoggerEx)\n");
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: RTLogLoggerEx returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogPrintf("hello ring-0 logger (RTLogPrintf)\n");
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("VMMR0Init: RTLogPrintf returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Associate the ring-0 EMT thread with the GVM
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * and initalize the GVMM and GMM per VM data.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = GVMMR0AssociateEMTWithVM(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (RT_SUCCESS(rc))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = GVMMR0InitVM(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync //if (RT_SUCCESS(rc))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync // rc = GMMR0InitVM(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (RT_SUCCESS(rc))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Init HWACCM.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = HWACCMR0Init(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync ASMSetFlags(fFlags);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (RT_SUCCESS(rc))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Init CPUM.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = CPUMR0Init(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (RT_SUCCESS(rc))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /* failed */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogSetDefaultInstanceThread(NULL, 0);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Terminates the R0 driver for a particular VM instance.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns VBox status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pVM The VM instance in question.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @thread EMT.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncstatic int VMMR0Term(PVM pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Deregister the logger.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync GVMMR0DisassociateEMTFromVM(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogSetDefaultInstanceThread(NULL, 0);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VINF_SUCCESS;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Calls the ring-3 host code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns VBox status code of the ring-3 call.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pVM The VM handle.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param enmOperation The operation.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param uArg The argument to the operation.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncVMMR0DECL(int) VMMR0CallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/** @todo profile this! */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pVM->vmm.s.enmCallHostOperation = enmOperation;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pVM->vmm.s.u64CallHostArg = uArg;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pVM->vmm.s.rcCallHost = VERR_INTERNAL_ERROR;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = vmmR0CallHostLongJmp(&pVM->vmm.s.CallHostR0JmpBuf, VINF_VMM_CALL_HOST);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (rc == VINF_SUCCESS)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = pVM->vmm.s.rcCallHost;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef VBOX_WITH_STATISTICS
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Record return code statistics
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pVM The VM handle.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param rc The status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncstatic void vmmR0RecordRC(PVM pVM, int rc)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
78df65edff21c11c537f38e736707ea434ab5623vboxsync /*
78df65edff21c11c537f38e736707ea434ab5623vboxsync * Collect statistics.
78df65edff21c11c537f38e736707ea434ab5623vboxsync */
78df65edff21c11c537f38e736707ea434ab5623vboxsync switch (rc)
78df65edff21c11c537f38e736707ea434ab5623vboxsync {
78df65edff21c11c537f38e736707ea434ab5623vboxsync case VINF_SUCCESS:
78df65edff21c11c537f38e736707ea434ab5623vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetNormal);
78df65edff21c11c537f38e736707ea434ab5623vboxsync break;
78df65edff21c11c537f38e736707ea434ab5623vboxsync case VINF_EM_RAW_INTERRUPT:
78df65edff21c11c537f38e736707ea434ab5623vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterrupt);
78df65edff21c11c537f38e736707ea434ab5623vboxsync break;
78df65edff21c11c537f38e736707ea434ab5623vboxsync case VINF_EM_RAW_INTERRUPT_HYPER:
78df65edff21c11c537f38e736707ea434ab5623vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterruptHyper);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_GUEST_TRAP:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetGuestTrap);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_RING_SWITCH:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRingSwitch);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_RING_SWITCH_INT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRingSwitchInt);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_EXCEPTION_PRIVILEGED:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetExceptionPrivilege);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_STALE_SELECTOR:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetStaleSelector);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_IRET_TRAP:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIRETTrap);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_IOM_HC_IOPORT_READ:
78df65edff21c11c537f38e736707ea434ab5623vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIORead);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_IOM_HC_IOPORT_WRITE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIOWrite);
78df65edff21c11c537f38e736707ea434ab5623vboxsync break;
78df65edff21c11c537f38e736707ea434ab5623vboxsync case VINF_IOM_HC_MMIO_READ:
78df65edff21c11c537f38e736707ea434ab5623vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIORead);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_IOM_HC_MMIO_WRITE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOWrite);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_IOM_HC_MMIO_READ_WRITE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOReadWrite);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PATM_HC_MMIO_PATCH_READ:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOPatchRead);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PATM_HC_MMIO_PATCH_WRITE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOPatchWrite);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_EMULATE_INSTR:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetEmulate);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PATCH_EMULATE_INSTR:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchEmulate);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetLDTFault);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetGDTFault);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIDTFault);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetTSSFault);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_EMULATE_INSTR_PD_FAULT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDFault);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_CSAM_PENDING_ACTION:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetCSAMTask);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PGM_SYNC_CR3:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetSyncCR3);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PATM_PATCH_INT3:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchInt3);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PATM_PATCH_TRAP_PF:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchPF);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PATM_PATCH_TRAP_GP:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchGP);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PATM_PENDING_IRQ_AFTER_IRET:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchIretIRQ);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VERR_REM_FLUSHED_PAGES_OVERFLOW:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPageOverflow);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RESCHEDULE_REM:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRescheduleREM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_TO_R3:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetToR3);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_TIMER_PENDING:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetTimerPending);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_INTERRUPT_PENDING:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterruptPending);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_VMM_CALL_HOST:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync switch (pVM->vmm.s.enmCallHostOperation)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMCALLHOST_PDM_LOCK:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDMLock);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMCALLHOST_PDM_QUEUE_FLUSH:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDMQueueFlush);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMCALLHOST_PGM_POOL_GROW:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMPoolGrow);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMCALLHOST_PGM_LOCK:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMLock);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRemReplay);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync case VMMCALLHOST_PGM_RAM_GROW_RANGE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMGrowRAM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMCALLHOST_VMM_LOGGER_FLUSH:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetLogFlush);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMCALLHOST_VM_SET_ERROR:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetVMSetError);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMCALLHOST_VM_SET_RUNTIME_ERROR:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetVMSetRuntimeError);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync default:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetCallHost);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PATM_DUPLICATE_FUNCTION:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPATMDuplicateFn);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_PGM_CHANGE_MODE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMChangeMode);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_RAW_EMULATE_INSTR_HLT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetEmulHlt);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VINF_EM_PENDING_REQUEST:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPendingRequest);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync default:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMisc);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync#endif /* VBOX_WITH_STATISTICS */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * The Ring 0 entry point, called by the interrupt gate.
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync *
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync * @returns VBox status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pVM The VM to operate on.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param enmOperation Which operation to execute.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pvArg Argument to the operation.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @remarks Assume called with interrupts disabled.
090c459b9e90ca46e2ce2b8c81533ade3b23f3e9vboxsync */
090c459b9e90ca46e2ce2b8c81533ade3b23f3e9vboxsyncVMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg)
090c459b9e90ca46e2ce2b8c81533ade3b23f3e9vboxsync{
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync switch (enmOperation)
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync {
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync#ifdef VBOX_WITH_IDT_PATCHING
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync /*
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync * Switch to GC.
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync * These calls return whatever the GC returns.
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync */
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync case VMMR0_DO_RAW_RUN:
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync {
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync /* Safety precaution as VMX disables the switcher. */
090c459b9e90ca46e2ce2b8c81533ade3b23f3e9vboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pVM->vmm.s.fSwitcherDisabled)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC);
090c459b9e90ca46e2ce2b8c81533ade3b23f3e9vboxsync register int rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pVM->vmm.s.iLastGCRc = rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef VBOX_WITH_STATISTICS
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync vmmR0RecordRC(pVM, rc);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * We'll let TRPM change the stack frame so our return is different.
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync * Just keep in mind that after the call, things have changed!
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync */
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync if ( rc == VINF_EM_RAW_INTERRUPT
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync || rc == VINF_EM_RAW_INTERRUPT_HYPER)
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync {
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync /*
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync * Don't trust the compiler to get this right.
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync * gcc -fomit-frame-pointer screws up big time here. This works fine in 64-bit
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync * mode too because we push the arguments on the stack in the IDT patch code.
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync */
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync# if defined(__GNUC__)
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync void *pvRet = (uint8_t *)__builtin_frame_address(0) + sizeof(void *);
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync# elif defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync void *pvRet = (uint8_t *)_AddressOfReturnAddress();
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync# elif defined(RT_ARCH_X86)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync void *pvRet = (uint8_t *)&pVM - sizeof(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync# else
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync# error "huh?"
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync# endif
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync if ( ((uintptr_t *)pvRet)[1] == (uintptr_t)pVM
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync && ((uintptr_t *)pvRet)[2] == (uintptr_t)enmOperation
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync && ((uintptr_t *)pvRet)[3] == (uintptr_t)pvArg)
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync TRPMR0SetupInterruptDispatcherFrame(pVM, pvRet);
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync else
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync {
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync# if defined(DEBUG) || defined(LOG_ENABLED)
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync static bool s_fHaveWarned = false;
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync if (!s_fHaveWarned)
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync {
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync s_fHaveWarned = true;
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync //RTLogPrintf("VMMR0.r0: The compiler can't find the stack frame!\n"); -- @todo export me!
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync RTLogComPrintf("VMMR0.r0: The compiler can't find the stack frame!\n");
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync }
a86135e41c89c7b599607649347a4240809c784bvboxsync# endif
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync TRPMR0DispatchHostInterrupt(pVM);
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync }
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync }
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync return rc;
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync }
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync /*
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync * Switch to GC to execute Hypervisor function.
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync */
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync case VMMR0_DO_CALL_HYPERVISOR:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /* Safety precaution as VMX disables the switcher. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pVM->vmm.s.fSwitcherDisabled)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /** @todo dispatch interrupts? */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync ASMSetFlags(fFlags);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * For profiling.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_NOP:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VINF_SUCCESS;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif /* VBOX_WITH_IDT_PATCHING */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync default:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * We're returning VERR_NOT_SUPPORT here so we've got something else
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * than -1 which the interrupt gate glue code might return.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync Log(("operation %#x is not supported\n", enmOperation));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * The Ring 0 entry point, called by the fast-ioctl path.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns VBox status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pVM The VM to operate on.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param enmOperation Which operation to execute.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @remarks Assume called with interrupts _enabled_.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncVMMR0DECL(int) VMMR0EntryFast(PVM pVM, VMMR0OPERATION enmOperation)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync switch (enmOperation)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Switch to GC and run guest raw mode code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Disable interrupts before doing the world switch.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_RAW_RUN:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /* Safety precaution as hwaccm disables the switcher. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (RT_LIKELY(!pVM->vmm.s.fSwitcherDisabled))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTCCUINTREG uFlags = ASMIntDisableFlags();
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pVM->vmm.s.iLastGCRc = rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if ( rc == VINF_EM_RAW_INTERRUPT
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || rc == VINF_EM_RAW_INTERRUPT_HYPER)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync TRPMR0DispatchHostInterrupt(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync ASMSetFlags(uFlags);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef VBOX_WITH_STATISTICS
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync vmmR0RecordRC(pVM, rc);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Run guest code using the available hardware acceleration technology.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Disable interrupts before we do anything interesting. On Windows we avoid
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * this by having the support driver raise the IRQL before calling us, this way
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * we hope to get away we page faults and later calling into the kernel.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_HWACC_RUN:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifndef RT_OS_WINDOWS /** @todo check other hosts */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTCCUINTREG uFlags = ASMIntDisableFlags();
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = HWACCMR0Enable(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (VBOX_SUCCESS(rc))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = vmmR0CallHostSetJmp(&pVM->vmm.s.CallHostR0JmpBuf, HWACCMR0RunGuestCode, pVM); /* this may resume code. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc2 = HWACCMR0Disable(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertRC(rc2);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pVM->vmm.s.iLastGCRc = rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifndef RT_OS_WINDOWS /** @todo check other hosts */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync ASMSetFlags(uFlags);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef VBOX_WITH_STATISTICS
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync vmmR0RecordRC(pVM, rc);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /* No special action required for external interrupts, just return. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * For profiling.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_NOP:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VINF_SUCCESS;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Impossible.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync default:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgFailed(("%#x\n", enmOperation));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * VMMR0EntryEx worker function, either called directly or when ever possible
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * called thru a longjmp so we can exit safely on failure.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns VBox status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pVM The VM to operate on.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param enmOperation Which operation to execute.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pReqHdr This points to a SUPVMMR0REQHDR packet. Optional.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param u64Arg Some simple constant argument.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @remarks Assume called with interrupts _enabled_.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncstatic int vmmR0EntryExWorker(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Common VM pointer validation.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (RT_UNLIKELY( !VALID_PTR(pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || ((uintptr_t)pVM & PAGE_OFFSET_MASK)))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p! (op=%d)\n", pVM, enmOperation);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_POINTER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (RT_UNLIKELY( pVM->enmVMState < VMSTATE_CREATING
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || pVM->enmVMState > VMSTATE_TERMINATED
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || pVM->pVMR0 != pVM))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p:{enmVMState=%d, .pVMR0=%p}! (op=%d)\n",
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pVM, pVM->enmVMState, pVM->pVMR0, enmOperation);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_POINTER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync switch (enmOperation)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * GVM requests
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GVMM_CREATE_VM:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pVM || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync SUPR0Printf("-> GVMMR0CreateVMReq\n");
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GVMM_DESTROY_VM:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pReqHdr || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GVMMR0DestroyVM(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GVMM_SCHED_HALT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pReqHdr)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GVMMR0SchedHalt(pVM, u64Arg);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GVMM_SCHED_WAKE_UP:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pReqHdr || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GVMMR0SchedWakeUp(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GVMM_SCHED_POLL:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pReqHdr || u64Arg > 1)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GVMMR0SchedPoll(pVM, (bool)u64Arg);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GVMM_QUERY_STATISTICS:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GVMM_RESET_STATISTICS:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Initialize the R0 part of a VM instance.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_VMMR0_INIT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VMMR0Init(pVM, (unsigned)u64Arg);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Terminate the R0 part of a VM instance.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_VMMR0_TERM:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VMMR0Term(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Setup the hardware accelerated raw-mode session.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_HWACC_SETUP_VM:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = HWACCMR0SetupVMX(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync ASMSetFlags(fFlags);
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync return rc;
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync }
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync /*
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync * Switch to GC to execute Hypervisor function.
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync */
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync case VMMR0_DO_CALL_HYPERVISOR:
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync {
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync /* Safety precaution as VMX disables the switcher. */
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync if (pVM->vmm.s.fSwitcherDisabled)
564cc620447c495b6ff9cbb9274e225692fe38dfvboxsync return VERR_NOT_SUPPORTED;
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync int rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync /** @todo dispatch interrupts? */
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync ASMSetFlags(fFlags);
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync return rc;
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync }
dbec828311ed2a5cf6fbc68fe4391d516ba4f92fvboxsync
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync /*
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync * PGM wrappers.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return PGMR0PhysAllocateHandyPages(pVM);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * GMM wrappers.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_INITIAL_RESERVATION:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GMMR0InitialReservationReq(pVM, (PGMMINITIALRESERVATIONREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_UPDATE_RESERVATION:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GMMR0UpdateReservationReq(pVM, (PGMMUPDATERESERVATIONREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_ALLOCATE_PAGES:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GMMR0AllocatePagesReq(pVM, (PGMMALLOCATEPAGESREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_FREE_PAGES:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GMMR0FreePagesReq(pVM, (PGMMFREEPAGESREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_BALLOONED_PAGES:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GMMR0BalloonedPagesReq(pVM, (PGMMBALLOONEDPAGESREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_DEFLATED_BALLOON:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pReqHdr)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GMMR0DeflatedBalloon(pVM, (uint32_t)u64Arg);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_MAP_UNMAP_CHUNK:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GMMR0MapUnmapChunkReq(pVM, (PGMMMAPUNMAPCHUNKREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_SEED_CHUNK:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pReqHdr)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return GMMR0SeedChunk(pVM, (RTR3PTR)u64Arg);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * A quick GCFGM mock-up.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /** @todo GCFGM with proper access control, ring-3 management interface and all that. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GCFGM_SET_VALUE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GCFGM_QUERY_VALUE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pVM || !pReqHdr || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync PGCFGMVALUEREQ pReq = (PGCFGMVALUEREQ)pReqHdr;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pReq->Hdr.cbReq != sizeof(*pReq))
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (enmOperation == VMMR0_DO_GCFGM_SET_VALUE)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = GVMMR0SetConfig(pReq->pSession, &pReq->szName[0], pReq->u64Value);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync //if (rc == VERR_CFGM_VALUE_NOT_FOUND)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync // rc = GMMR0SetConfig(pReq->pSession, &pReq->szName[0], pReq->u64Value);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync else
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = GVMMR0QueryConfig(pReq->pSession, &pReq->szName[0], &pReq->u64Value);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync //if (rc == VERR_CFGM_VALUE_NOT_FOUND)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync // rc = GMMR0QueryConfig(pReq->pSession, &pReq->szName[0], &pReq->u64Value);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return rc;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Requests to the internal networking service.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_INTNET_OPEN:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!pVM || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!g_pIntNet)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return INTNETR0OpenReq(g_pIntNet, pVM->pSession, (PINTNETOPENREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_INTNET_IF_CLOSE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!pVM || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!g_pIntNet)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return INTNETR0IfCloseReq(g_pIntNet, (PINTNETIFCLOSEREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_INTNET_IF_GET_RING3_BUFFER:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!pVM || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!g_pIntNet)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return INTNETR0IfGetRing3BufferReq(g_pIntNet, (PINTNETIFGETRING3BUFFERREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!pVM || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!g_pIntNet)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return INTNETR0IfSetPromiscuousModeReq(g_pIntNet, (PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_INTNET_IF_SEND:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!pVM || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
37a7e3e6f9ce5f6cabeb3f734044e9e8ca9cb1bfvboxsync if (!g_pIntNet)
37a7e3e6f9ce5f6cabeb3f734044e9e8ca9cb1bfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return INTNETR0IfSendReq(g_pIntNet, (PINTNETIFSENDREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_INTNET_IF_WAIT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!pVM || u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_INVALID_PARAMETER;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!g_pIntNet)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return INTNETR0IfWaitReq(g_pIntNet, (PINTNETIFWAITREQ)pReqHdr);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif /* VBOX_WITH_INTERNAL_NETWORKING */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * For profiling.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_NOP:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VINF_SUCCESS;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * For testing Ring-0 APIs invoked in this environment.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_TESTS:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /** @todo make new test */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VINF_SUCCESS;
090c459b9e90ca46e2ce2b8c81533ade3b23f3e9vboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync default:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * We're returning VERR_NOT_SUPPORT here so we've got something else
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * than -1 which the interrupt gate glue code might return.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync Log(("operation %#x is not supported\n", enmOperation));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return VERR_NOT_SUPPORTED;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Argument for vmmR0EntryExWrapper containing the argument s ofr VMMR0EntryEx.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsynctypedef struct VMMR0ENTRYEXARGS
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync PVM pVM;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync VMMR0OPERATION enmOperation;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync PSUPVMMR0REQHDR pReq;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync uint64_t u64Arg;
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync} VMMR0ENTRYEXARGS;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/** Pointer to a vmmR0EntryExWrapper argument package. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsynctypedef VMMR0ENTRYEXARGS *PVMMR0ENTRYEXARGS;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * This is just a longjmp wrapper function for VMMR0EntryEx calls.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns VBox status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pvArgs The argument package
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsyncstatic int vmmR0EntryExWrapper(void *pvArgs)
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync{
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM,
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync ((PVMMR0ENTRYEXARGS)pvArgs)->enmOperation,
af0a09edb4c1431b606fe207d4138da008f67f13vboxsync ((PVMMR0ENTRYEXARGS)pvArgs)->pReq,
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync ((PVMMR0ENTRYEXARGS)pvArgs)->u64Arg);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * The Ring 0 entry point, called by the support library (SUP).
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns VBox status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pVM The VM to operate on.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param enmOperation Which operation to execute.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pReq This points to a SUPVMMR0REQHDR packet. Optional.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param u64Arg Some simple constant argument.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @remarks Assume called with interrupts _enabled_.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncVMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Requests that should only happen on the EMT thread will be
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * wrapped in a setjmp so we can assert without causing trouble.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if ( VALID_PTR(pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync && pVM->pVMR0)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync switch (enmOperation)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_VMMR0_INIT:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_VMMR0_TERM:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_INITIAL_RESERVATION:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_UPDATE_RESERVATION:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_ALLOCATE_PAGES:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_FREE_PAGES:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_BALLOONED_PAGES:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_DEFLATED_BALLOON:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_MAP_UNMAP_CHUNK:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case VMMR0_DO_GMM_SEED_CHUNK:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /** @todo validate this EMT claim... GVM knows. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync VMMR0ENTRYEXARGS Args;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync Args.pVM = pVM;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync Args.enmOperation = enmOperation;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync Args.pReq = pReq;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync Args.u64Arg = u64Arg;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return vmmR0CallHostSetJmpEx(&pVM->vmm.s.CallHostR0JmpBuf, vmmR0EntryExWrapper, &Args);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync default:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync break;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return vmmR0EntryExWorker(pVM, enmOperation, pReq, u64Arg);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Internal R0 logger worker: Flush logger.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pLogger The logger instance to flush.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @remark This function must be exported!
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncVMMR0DECL(void) vmmR0LoggerFlush(PRTLOGGER pLogger)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Convert the pLogger into a VM handle and 'call' back to Ring-3.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * (This is a bit paranoid code.)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync PVMMR0LOGGER pR0Logger = (PVMMR0LOGGER)((uintptr_t)pLogger - RT_OFFSETOF(VMMR0LOGGER, Logger));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if ( !VALID_PTR(pR0Logger)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || !VALID_PTR(pR0Logger + 1)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || !VALID_PTR(pLogger)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || pLogger->u32Magic != RTLOGGER_MAGIC)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("vmmR0LoggerFlush: pLogger=%p!\n", pLogger));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync PVM pVM = pR0Logger->pVM;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if ( !VALID_PTR(pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync || pVM->pVMR0 != pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("vmmR0LoggerFlush: pVM=%p! pLogger=%p\n", pVM, pLogger));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /*
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Check that the jump buffer is armed.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef RT_ARCH_X86
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!pVM->vmm.s.CallHostR0JmpBuf.eip)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#else
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (!pVM->vmm.s.CallHostR0JmpBuf.rip)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogCom(("vmmR0LoggerFlush: Jump buffer isn't armed!\n"));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pLogger->offScratch = 0;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync VMMR0CallHost(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Jump back to ring-3 if we're the EMT and the longjmp is armed.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns true if the breakpoint should be hit, false if it should be ignored.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @remark The RTDECL() makes this a bit difficult to override on windows. Sorry.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncDECLEXPORT(bool) RTCALL RTAssertDoBreakpoint(void)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync{
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync PVM pVM = GVMMR0GetVMByEMT(NIL_RTNATIVETHREAD);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pVM)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#ifdef RT_ARCH_X86
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pVM->vmm.s.CallHostR0JmpBuf.eip)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#else
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync if (pVM->vmm.s.CallHostR0JmpBuf.rip)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync {
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return RT_FAILURE_NP(rc);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /* Never ever trigger breakpoints in ring 0 */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync return false;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync# undef LOG_GROUP
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync# define LOG_GROUP LOG_GROUP_EM
090c459b9e90ca46e2ce2b8c81533ade3b23f3e9vboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/**
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Override this so we can push
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pszExpr Expression. Can be NULL.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param uLine Location line number.
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync * @param pszFile Location file name.
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync * @param pszFunction Location function name.
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync * @remark This API exists in HC Ring-3 and GC.
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync */
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsyncDECLEXPORT(void) RTCALL AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync{
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync SUPR0Printf("\n!!R0-Assertion Failed!!\n"
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync "Expression: %s\n"
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync "Location : %s(%d) %s\n",
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync pszExpr, pszFile, uLine, pszFunction);
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync LogRel(("\n!!R0-Assertion Failed!!\n"
11c2b573e2625474a51ae55ee1f3f82936f125davboxsync "Expression: %s\n"
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync "Location : %s(%d) %s\n",
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync pszExpr, pszFile, uLine, pszFunction));
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync}
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync/**
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync * Callback for RTLogFormatV which writes to the com port.
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync * See PFNLOGOUTPUT() for details.
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync */
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsyncstatic DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars)
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync{
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync for (size_t i = 0; i < cbChars; i++)
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync {
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync LogRel(("%c", pachChars[i])); /** @todo this isn't any release logging in ring-0 from what I can tell... */
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync SUPR0Printf("%c", pachChars[i]);
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync }
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync return cbChars;
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync}
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsyncDECLEXPORT(void) RTCALL AssertMsg2(const char *pszFormat, ...)
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync{
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync PRTLOGGER pLog = RTLogDefaultInstance();
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync if (pLog)
b2e90826ea719b22452d1ff7b977d4f40995b428vboxsync {
04b02ffb8824a60fd37777bc1f7d2f35104a274cvboxsync va_list args;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync va_start(args, pszFormat);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync RTLogFormatV(rtLogOutput, pLog, pszFormat, args);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync va_end(args);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync }
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync}
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync
be9960565d2df0031f0e6c8a4610f5f0ae8c1845vboxsync