VMMR0.cpp revision ea416cf4cff6b3415142253cbee1752b5c7947c7
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync/* $Id$ */
b711a01730152421a900e5f4e237cfb848c9c4fdvboxsync/** @file
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync * VMM - Host Context Ring 0.
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync */
2f14f4556ae74ad40719bc9690534693abb71868vboxsync
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync/*
1612ddf488e6d1a459dc02cd7078215985f87081vboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync *
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync * available from http://www.virtualbox.org. This file is free software;
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync * you can redistribute it and/or modify it under the terms of the GNU
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync * General Public License as published by the Free Software Foundation,
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
94872a0e88ab4f38c786fcf617ddeb4b63a76957vboxsync *
78a072e1b56619e3230735ae073668311232ec94vboxsync * If you received this file as part of a commercial VirtualBox
78a072e1b56619e3230735ae073668311232ec94vboxsync * distribution, then only the terms of your commercial VirtualBox
78a072e1b56619e3230735ae073668311232ec94vboxsync * license agreement apply instead of the previous paragraph.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync
c3d2b15ad840b405062f4c2c6b127d6fc107c7b2vboxsync
c3d2b15ad840b405062f4c2c6b127d6fc107c7b2vboxsync/*******************************************************************************
c3d2b15ad840b405062f4c2c6b127d6fc107c7b2vboxsync* Header Files *
c3d2b15ad840b405062f4c2c6b127d6fc107c7b2vboxsync*******************************************************************************/
c3d2b15ad840b405062f4c2c6b127d6fc107c7b2vboxsync#define LOG_GROUP LOG_GROUP_VMM
c3d2b15ad840b405062f4c2c6b127d6fc107c7b2vboxsync#ifdef __AMD64__ /** @todo fix logging on __AMD64__ (swapgs) - this has been fixed now. please remove. */
78a072e1b56619e3230735ae073668311232ec94vboxsync# define LOG_DISABLED
b0c4bd49112a99f00ef48b7a8eae6fb310a62bdavboxsync#endif
b0c4bd49112a99f00ef48b7a8eae6fb310a62bdavboxsync#include <VBox/vmm.h>
b0c4bd49112a99f00ef48b7a8eae6fb310a62bdavboxsync#include <VBox/sup.h>
78a072e1b56619e3230735ae073668311232ec94vboxsync#include <VBox/trpm.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <VBox/cpum.h>
78a072e1b56619e3230735ae073668311232ec94vboxsync#include <VBox/stam.h>
b0c4bd49112a99f00ef48b7a8eae6fb310a62bdavboxsync#include <VBox/tm.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include "VMMInternal.h"
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <VBox/vm.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <VBox/intnet.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <VBox/hwaccm.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <VBox/err.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <VBox/version.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <VBox/log.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <iprt/assert.h>
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#include <iprt/stdarg.h>
78a072e1b56619e3230735ae073668311232ec94vboxsync
d5d45608052fd506e4114bf112df6efae7fcd8a7vboxsync#if defined(_MSC_VER) && defined(__AMD64__) /** @todo check this with with VC7! */
9be72bf71509dd721ffa1df70ead200abf30afd8vboxsync# pragma intrinsic(_AddressOfReturnAddress)
e7184fff6d89903aed623860629a05047960ac2dvboxsync#endif
e7184fff6d89903aed623860629a05047960ac2dvboxsync
e7184fff6d89903aed623860629a05047960ac2dvboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync/*******************************************************************************
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync* Internal Functions *
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync*******************************************************************************/
cc260ed3418d1fd2771d0395f818f76808b60238vboxsyncstatic int VMMR0Init(PVM pVM, unsigned uVersion);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsyncstatic int VMMR0Term(PVM pVM);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync__BEGIN_DECLS
cc260ed3418d1fd2771d0395f818f76808b60238vboxsyncVMMR0DECL(int) ModuleInit(void);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsyncVMMR0DECL(void) ModuleTerm(void);
78a072e1b56619e3230735ae073668311232ec94vboxsync__END_DECLS
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync//#define DEBUG_NO_RING0_ASSERTIONS
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#ifdef DEBUG_NO_RING0_ASSERTIONS
cc260ed3418d1fd2771d0395f818f76808b60238vboxsyncstatic PVM g_pVMAssert = 0;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#endif
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync/*******************************************************************************
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync* Global Variables *
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync*******************************************************************************/
78a072e1b56619e3230735ae073668311232ec94vboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
78a072e1b56619e3230735ae073668311232ec94vboxsync/** Pointer to the internal networking service instance. */
78a072e1b56619e3230735ae073668311232ec94vboxsyncPINTNET g_pIntNet = 0;
78a072e1b56619e3230735ae073668311232ec94vboxsync#endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync/**
78a072e1b56619e3230735ae073668311232ec94vboxsync * Initialize the module.
78a072e1b56619e3230735ae073668311232ec94vboxsync * This is called when we're first loaded.
78a072e1b56619e3230735ae073668311232ec94vboxsync *
c7c6718a3ec95ca32bf4f2e5311b871e95c3b195vboxsync * @returns 0 on success.
78a072e1b56619e3230735ae073668311232ec94vboxsync * @returns VBox status on failure.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsyncVMMR0DECL(int) ModuleInit(void)
78a072e1b56619e3230735ae073668311232ec94vboxsync{
78a072e1b56619e3230735ae073668311232ec94vboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
78a072e1b56619e3230735ae073668311232ec94vboxsync LogFlow(("ModuleInit: g_pIntNet=%p\n", g_pIntNet));
78a072e1b56619e3230735ae073668311232ec94vboxsync g_pIntNet = NULL;
78a072e1b56619e3230735ae073668311232ec94vboxsync LogFlow(("ModuleInit: g_pIntNet=%p should be NULL now...\n", g_pIntNet));
78a072e1b56619e3230735ae073668311232ec94vboxsync int rc = INTNETR0Create(&g_pIntNet);
78a072e1b56619e3230735ae073668311232ec94vboxsync if (VBOX_SUCCESS(rc))
78a072e1b56619e3230735ae073668311232ec94vboxsync {
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogFlow(("ModuleInit: returns success. g_pIntNet=%p\n", g_pIntNet));
08c4185261c17943cff6cc94522579696eeeb478vboxsync return 0;
08c4185261c17943cff6cc94522579696eeeb478vboxsync }
08c4185261c17943cff6cc94522579696eeeb478vboxsync g_pIntNet = NULL;
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogFlow(("ModuleTerm: returns %Vrc\n", rc));
08c4185261c17943cff6cc94522579696eeeb478vboxsync return rc;
08c4185261c17943cff6cc94522579696eeeb478vboxsync#else
08c4185261c17943cff6cc94522579696eeeb478vboxsync return 0;
08c4185261c17943cff6cc94522579696eeeb478vboxsync#endif
08c4185261c17943cff6cc94522579696eeeb478vboxsync}
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync/**
08c4185261c17943cff6cc94522579696eeeb478vboxsync * Terminate the module.
08c4185261c17943cff6cc94522579696eeeb478vboxsync * This is called when we're finally unloaded.
08c4185261c17943cff6cc94522579696eeeb478vboxsync */
08c4185261c17943cff6cc94522579696eeeb478vboxsyncVMMR0DECL(void) ModuleTerm(void)
08c4185261c17943cff6cc94522579696eeeb478vboxsync{
08c4185261c17943cff6cc94522579696eeeb478vboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogFlow(("ModuleTerm:\n"));
08c4185261c17943cff6cc94522579696eeeb478vboxsync if (g_pIntNet)
08c4185261c17943cff6cc94522579696eeeb478vboxsync {
08c4185261c17943cff6cc94522579696eeeb478vboxsync INTNETR0Destroy(g_pIntNet);
78a072e1b56619e3230735ae073668311232ec94vboxsync g_pIntNet = NULL;
08c4185261c17943cff6cc94522579696eeeb478vboxsync }
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogFlow(("ModuleTerm: returns\n"));
9726c89eba6e777f3eb4d57f65ca6171a2241d29vboxsync#endif
08c4185261c17943cff6cc94522579696eeeb478vboxsync}
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync
da31d917654e0b617e7a9bf8b0cf786136edf8e8vboxsync/**
08c4185261c17943cff6cc94522579696eeeb478vboxsync * Initaties the R0 driver for a particular VM instance.
08c4185261c17943cff6cc94522579696eeeb478vboxsync *
08c4185261c17943cff6cc94522579696eeeb478vboxsync * @returns VBox status code.
08c4185261c17943cff6cc94522579696eeeb478vboxsync *
08c4185261c17943cff6cc94522579696eeeb478vboxsync * @param pVM The VM instance in question.
08c4185261c17943cff6cc94522579696eeeb478vboxsync * @param uVersion The minimum module version required.
08c4185261c17943cff6cc94522579696eeeb478vboxsync */
08c4185261c17943cff6cc94522579696eeeb478vboxsyncstatic int VMMR0Init(PVM pVM, unsigned uVersion)
08c4185261c17943cff6cc94522579696eeeb478vboxsync{
08c4185261c17943cff6cc94522579696eeeb478vboxsync /*
08c4185261c17943cff6cc94522579696eeeb478vboxsync * Check if compatible version.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
08c4185261c17943cff6cc94522579696eeeb478vboxsync if ( uVersion != VBOX_VERSION
08c4185261c17943cff6cc94522579696eeeb478vboxsync && ( VBOX_GET_VERSION_MAJOR(uVersion) != VBOX_VERSION_MAJOR
78a072e1b56619e3230735ae073668311232ec94vboxsync || VBOX_GET_VERSION_MINOR(uVersion) < VBOX_VERSION_MINOR))
08c4185261c17943cff6cc94522579696eeeb478vboxsync return VERR_VERSION_MISMATCH;
08c4185261c17943cff6cc94522579696eeeb478vboxsync if ( !VALID_PTR(pVM)
08c4185261c17943cff6cc94522579696eeeb478vboxsync || pVM->pVMR0 != pVM)
08c4185261c17943cff6cc94522579696eeeb478vboxsync return VERR_INVALID_PARAMETER;
78a072e1b56619e3230735ae073668311232ec94vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync /*
a6ab77f04b22f0de7691f50dfdee8196024ce26dvboxsync * Register the EMT R0 logger instance.
034b3d77b1a08b77b1fa9bfd7489997421713f15vboxsync */
a6ab77f04b22f0de7691f50dfdee8196024ce26dvboxsync PVMMR0LOGGER pR0Logger = pVM->vmm.s.pR0Logger;
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync if (pR0Logger)
a6ab77f04b22f0de7691f50dfdee8196024ce26dvboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync#if 0 /* testing of the logger. */
9726c89eba6e777f3eb4d57f65ca6171a2241d29vboxsync LogCom(("VMMR0Init: before %p\n", RTLogDefaultInstance()));
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogCom(("VMMR0Init: pfnFlush=%p actual=%p\n", pR0Logger->Logger.pfnFlush, vmmR0LoggerFlush));
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogCom(("VMMR0Init: pfnLogger=%p actual=%p\n", pR0Logger->Logger.pfnLogger, vmmR0LoggerWrapper));
78a072e1b56619e3230735ae073668311232ec94vboxsync LogCom(("VMMR0Init: offScratch=%d fFlags=%#x fDestFlags=%#x\n", pR0Logger->Logger.offScratch, pR0Logger->Logger.fFlags, pR0Logger->Logger.fDestFlags));
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogCom(("VMMR0Init: after %p reg\n", RTLogDefaultInstance()));
08c4185261c17943cff6cc94522579696eeeb478vboxsync RTLogSetDefaultInstanceThread(NULL, 0);
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogCom(("VMMR0Init: after %p dereg\n", RTLogDefaultInstance()));
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogCom(("VMMR0Init: returned succesfully from direct logger call.\n"));
08c4185261c17943cff6cc94522579696eeeb478vboxsync pR0Logger->Logger.pfnFlush(&pR0Logger->Logger);
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogCom(("VMMR0Init: returned succesfully from direct flush call.\n"));
08c4185261c17943cff6cc94522579696eeeb478vboxsync
da31d917654e0b617e7a9bf8b0cf786136edf8e8vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
78a072e1b56619e3230735ae073668311232ec94vboxsync LogCom(("VMMR0Init: after %p reg2\n", RTLogDefaultInstance()));
08c4185261c17943cff6cc94522579696eeeb478vboxsync pR0Logger->Logger.pfnLogger("hello ring-0 logger\n");
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogCom(("VMMR0Init: returned succesfully from direct logger call (2). offScratch=%d\n", pR0Logger->Logger.offScratch));
08c4185261c17943cff6cc94522579696eeeb478vboxsync RTLogSetDefaultInstanceThread(NULL, 0);
9726c89eba6e777f3eb4d57f65ca6171a2241d29vboxsync LogCom(("VMMR0Init: after %p dereg2\n", RTLogDefaultInstance()));
08c4185261c17943cff6cc94522579696eeeb478vboxsync
da31d917654e0b617e7a9bf8b0cf786136edf8e8vboxsync RTLogLoggerEx(&pR0Logger->Logger, 0, ~0U, "hello ring-0 logger (RTLogLoggerEx)\n");
08c4185261c17943cff6cc94522579696eeeb478vboxsync LogCom(("VMMR0Init: RTLogLoggerEx returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
08c4185261c17943cff6cc94522579696eeeb478vboxsync#endif
08c4185261c17943cff6cc94522579696eeeb478vboxsync RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Init VMXM.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync HWACCMR0Init(pVM);
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Init CPUM.
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync */
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync int rc = CPUMR0Init(pVM);
78a072e1b56619e3230735ae073668311232ec94vboxsync
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync if (RT_FAILURE(rc))
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync RTLogSetDefaultInstanceThread(NULL, 0);
78a072e1b56619e3230735ae073668311232ec94vboxsync return rc;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync}
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync/**
78a072e1b56619e3230735ae073668311232ec94vboxsync * Terminates the R0 driver for a particular VM instance.
78a072e1b56619e3230735ae073668311232ec94vboxsync *
78a072e1b56619e3230735ae073668311232ec94vboxsync * @returns VBox status code.
78a072e1b56619e3230735ae073668311232ec94vboxsync *
78a072e1b56619e3230735ae073668311232ec94vboxsync * @param pVM The VM instance in question.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsyncstatic int VMMR0Term(PVM pVM)
78a072e1b56619e3230735ae073668311232ec94vboxsync{
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync /*
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync * Deregister the logger.
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync */
22ecc39cb2e9aeb958d702b60fd677e8df0cdc70vboxsync RTLogSetDefaultInstanceThread(NULL, 0);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync return VINF_SUCCESS;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync}
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync/**
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync * Calls the ring-3 host code.
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync *
58798710f0fd506acfbef1cece482642d0447550vboxsync * @returns VBox status code of the ring-3 call.
60a6d709c252770b3830c85deac9c493625e3f52vboxsync * @param pVM The VM handle.
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync * @param enmOperation The operation.
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync * @param uArg The argument to the operation.
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync */
cc260ed3418d1fd2771d0395f818f76808b60238vboxsyncVMMR0DECL(int) VMMR0CallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg)
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync{
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync/** @todo profile this! */
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync pVM->vmm.s.enmCallHostOperation = enmOperation;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync pVM->vmm.s.u64CallHostArg = uArg;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync pVM->vmm.s.rcCallHost = VERR_INTERNAL_ERROR;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync int rc = vmmR0CallHostLongJmp(&pVM->vmm.s.CallHostR0JmpBuf, VINF_VMM_CALL_HOST);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync if (rc == VINF_SUCCESS)
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync rc = pVM->vmm.s.rcCallHost;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync return rc;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync}
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#ifdef VBOX_WITH_STATISTICS
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync/**
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync * Record return code statistics
2a7322928382e52db8e320d19df4f03dee16b3edvboxsync * @param pVM The VM handle.
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync * @param rc The status code.
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync */
cc260ed3418d1fd2771d0395f818f76808b60238vboxsyncstatic void vmmR0RecordRC(PVM pVM, int rc)
78a072e1b56619e3230735ae073668311232ec94vboxsync{
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync * Collect statistics.
59bb2da0ef97dc8c9d0821ac921728f515623ac5vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync switch (rc)
78a072e1b56619e3230735ae073668311232ec94vboxsync {
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync case VINF_SUCCESS:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetNormal);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_INTERRUPT:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterrupt);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_INTERRUPT_HYPER:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterruptHyper);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_GUEST_TRAP:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetGuestTrap);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_RING_SWITCH:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRingSwitch);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_RING_SWITCH_INT:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRingSwitchInt);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_EXCEPTION_PRIVILEGED:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetExceptionPrivilege);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_STALE_SELECTOR:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetStaleSelector);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_IRET_TRAP:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIRETTrap);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_IOM_HC_IOPORT_READ:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIORead);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_IOM_HC_IOPORT_WRITE:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIOWrite);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_IOM_HC_IOPORT_READWRITE:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIOReadWrite);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_IOM_HC_MMIO_READ:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIORead);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_IOM_HC_MMIO_WRITE:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOWrite);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_IOM_HC_MMIO_READ_WRITE:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOReadWrite);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_PATM_HC_MMIO_PATCH_READ:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOPatchRead);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_PATM_HC_MMIO_PATCH_WRITE:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMMIOPatchWrite);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_EMULATE_INSTR:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetEmulate);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_PATCH_EMULATE_INSTR:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchEmulate);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync case VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT:
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetLDTFault);
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync break;
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync case VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetGDTFault);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetIDTFault);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetTSSFault);
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync break;
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync case VINF_EM_RAW_EMULATE_INSTR_PD_FAULT:
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDFault);
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_CSAM_PENDING_ACTION:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetCSAMTask);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_PGM_SYNC_CR3:
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetSyncCR3);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_PATM_PATCH_INT3:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchInt3);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync case VINF_PATM_PATCH_TRAP_PF:
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchPF);
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync break;
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync case VINF_PATM_PATCH_TRAP_GP:
156101683587682f6d63b4af322f611d90b77fcevboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchGP);
156101683587682f6d63b4af322f611d90b77fcevboxsync break;
156101683587682f6d63b4af322f611d90b77fcevboxsync case VINF_PATM_PENDING_IRQ_AFTER_IRET:
156101683587682f6d63b4af322f611d90b77fcevboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPatchIretIRQ);
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VERR_REM_FLUSHED_PAGES_OVERFLOW:
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPageOverflow);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync case VINF_EM_RESCHEDULE_REM:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRescheduleREM);
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_TO_R3:
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetToR3);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync case VINF_EM_RAW_TIMER_PENDING:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetTimerPending);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync break;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync case VINF_EM_RAW_INTERRUPT_PENDING:
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetInterruptPending);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync break;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync case VINF_VMM_CALL_HOST:
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync switch (pVM->vmm.s.enmCallHostOperation)
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync {
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync case VMMCALLHOST_PDM_LOCK:
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDMLock);
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync break;
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync case VMMCALLHOST_PDM_QUEUE_FLUSH:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPDMQueueFlush);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMCALLHOST_PGM_POOL_GROW:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMPoolGrow);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMCALLHOST_PGM_LOCK:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMLock);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetRemReplay);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMCALLHOST_PGM_RAM_GROW_RANGE:
58798710f0fd506acfbef1cece482642d0447550vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMGrowRAM);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMCALLHOST_VMM_LOGGER_FLUSH:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetLogFlush);
58798710f0fd506acfbef1cece482642d0447550vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMCALLHOST_VM_SET_ERROR:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetVMSetError);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMCALLHOST_VM_SET_RUNTIME_ERROR:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetVMSetRuntimeError);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync default:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetCallHost);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
2a7322928382e52db8e320d19df4f03dee16b3edvboxsync }
2a7322928382e52db8e320d19df4f03dee16b3edvboxsync break;
2a7322928382e52db8e320d19df4f03dee16b3edvboxsync case VINF_PATM_DUPLICATE_FUNCTION:
2a7322928382e52db8e320d19df4f03dee16b3edvboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPATMDuplicateFn);
2a7322928382e52db8e320d19df4f03dee16b3edvboxsync break;
2a7322928382e52db8e320d19df4f03dee16b3edvboxsync case VINF_PGM_CHANGE_MODE:
58798710f0fd506acfbef1cece482642d0447550vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPGMChangeMode);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_EMULATE_INSTR_HLT:
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetEmulHlt);
78a072e1b56619e3230735ae073668311232ec94vboxsync break;
58798710f0fd506acfbef1cece482642d0447550vboxsync case VINF_EM_PENDING_REQUEST:
58798710f0fd506acfbef1cece482642d0447550vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetPendingRequest);
58798710f0fd506acfbef1cece482642d0447550vboxsync break;
58798710f0fd506acfbef1cece482642d0447550vboxsync default:
58798710f0fd506acfbef1cece482642d0447550vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatGCRetMisc);
58798710f0fd506acfbef1cece482642d0447550vboxsync break;
58798710f0fd506acfbef1cece482642d0447550vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync}
78a072e1b56619e3230735ae073668311232ec94vboxsync#endif /* VBOX_WITH_STATISTICS */
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync/**
78a072e1b56619e3230735ae073668311232ec94vboxsync * The Ring 0 entry point, called by the support library (SUP).
78a072e1b56619e3230735ae073668311232ec94vboxsync *
78a072e1b56619e3230735ae073668311232ec94vboxsync * @returns VBox status code.
78a072e1b56619e3230735ae073668311232ec94vboxsync * @param pVM The VM to operate on.
78a072e1b56619e3230735ae073668311232ec94vboxsync * @param uOperation Which operation to execute. (VMMR0OPERATION)
78a072e1b56619e3230735ae073668311232ec94vboxsync * @param pvArg Argument to the operation.
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync */
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsyncVMMR0DECL(int) VMMR0Entry(PVM pVM, unsigned /* make me an enum */ uOperation, void *pvArg)
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync{
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync switch (uOperation)
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Switch to GC.
78a072e1b56619e3230735ae073668311232ec94vboxsync * These calls return whatever the GC returns.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync case VMMR0_DO_RAW_RUN:
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync {
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync /* Safety precaution as VMX disables the switcher. */
78a072e1b56619e3230735ae073668311232ec94vboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
78a072e1b56619e3230735ae073668311232ec94vboxsync if (pVM->vmm.s.fSwitcherDisabled)
78a072e1b56619e3230735ae073668311232ec94vboxsync return VERR_NOT_SUPPORTED;
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC);
78a072e1b56619e3230735ae073668311232ec94vboxsync register int rc;
78a072e1b56619e3230735ae073668311232ec94vboxsync pVM->vmm.s.iLastGCRc = rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync#ifdef VBOX_WITH_STATISTICS
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync vmmR0RecordRC(pVM, rc);
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync#endif
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Check if there is an exit R0 action associated with the return code.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync switch (rc)
78a072e1b56619e3230735ae073668311232ec94vboxsync {
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Default - no action, just return.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync default:
58798710f0fd506acfbef1cece482642d0447550vboxsync return rc;
fca81330c993457cc8047a46eec3d09b8e38da90vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * We'll let TRPM change the stack frame so our return is different.
78a072e1b56619e3230735ae073668311232ec94vboxsync * Just keep in mind that after the call, things have changed!
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_INTERRUPT:
78a072e1b56619e3230735ae073668311232ec94vboxsync case VINF_EM_RAW_INTERRUPT_HYPER:
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync#ifdef VBOX_WITHOUT_IDT_PATCHING
40d48df41519667fa639cfe552c097210b9685acvboxsync TRPMR0DispatchHostInterrupt(pVM);
78a072e1b56619e3230735ae073668311232ec94vboxsync#else /* !VBOX_WITHOUT_IDT_PATCHING */
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Don't trust the compiler to get this right.
78a072e1b56619e3230735ae073668311232ec94vboxsync * gcc -fomit-frame-pointer screws up big time here. This works fine in 64-bit
78a072e1b56619e3230735ae073668311232ec94vboxsync * mode too because we push the arguments on the stack in the IDT patch code.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync# if defined(__GNUC__)
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync void *pvRet = (uint8_t *)__builtin_frame_address(0) + sizeof(void *);
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync# elif defined(_MSC_VER) && defined(__AMD64__) /** @todo check this with with VC7! */
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync void *pvRet = (uint8_t *)_AddressOfReturnAddress();
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync# elif defined(__X86__)
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync void *pvRet = (uint8_t *)&pVM - sizeof(pVM);
b357ffdbc9fd30f5187620831737367bb1830fefvboxsync# else
78a072e1b56619e3230735ae073668311232ec94vboxsync# error "huh?"
78a072e1b56619e3230735ae073668311232ec94vboxsync# endif
78a072e1b56619e3230735ae073668311232ec94vboxsync if ( ((uintptr_t *)pvRet)[1] == (uintptr_t)pVM
78a072e1b56619e3230735ae073668311232ec94vboxsync && ((uintptr_t *)pvRet)[2] == (uintptr_t)uOperation
78a072e1b56619e3230735ae073668311232ec94vboxsync && ((uintptr_t *)pvRet)[3] == (uintptr_t)pvArg)
78a072e1b56619e3230735ae073668311232ec94vboxsync TRPMR0SetupInterruptDispatcherFrame(pVM, pvRet);
78a072e1b56619e3230735ae073668311232ec94vboxsync else
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync# if defined(DEBUG) || defined(LOG_ENABLED)
78a072e1b56619e3230735ae073668311232ec94vboxsync static bool s_fHaveWarned = false;
78a072e1b56619e3230735ae073668311232ec94vboxsync if (!s_fHaveWarned)
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync s_fHaveWarned = true;
78a072e1b56619e3230735ae073668311232ec94vboxsync //RTLogPrintf("VMMR0.r0: The compiler can't find the stack frame!\n"); -- @todo export me!
78a072e1b56619e3230735ae073668311232ec94vboxsync RTLogComPrintf("VMMR0.r0: The compiler can't find the stack frame!\n");
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync# endif
78a072e1b56619e3230735ae073668311232ec94vboxsync TRPMR0DispatchHostInterrupt(pVM);
78a072e1b56619e3230735ae073668311232ec94vboxsync }
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync#endif /* !VBOX_WITHOUT_IDT_PATCHING */
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync return rc;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync /* Won't get here! */
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync break;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Run guest code using the available hardware acceleration technology.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMR0_DO_HWACC_RUN:
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync int rc;
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC);
78a072e1b56619e3230735ae073668311232ec94vboxsync rc = HWACCMR0Enable(pVM);
78a072e1b56619e3230735ae073668311232ec94vboxsync if (VBOX_SUCCESS(rc))
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync#ifdef DEBUG_NO_RING0_ASSERTIONS
78a072e1b56619e3230735ae073668311232ec94vboxsync g_pVMAssert = pVM;
78a072e1b56619e3230735ae073668311232ec94vboxsync#endif
78a072e1b56619e3230735ae073668311232ec94vboxsync rc = vmmR0CallHostSetJmp(&pVM->vmm.s.CallHostR0JmpBuf, HWACCMR0RunGuestCode, pVM); /* this may resume code. */
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync#ifdef DEBUG_NO_RING0_ASSERTIONS
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync g_pVMAssert = 0;
78a072e1b56619e3230735ae073668311232ec94vboxsync#endif
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync int rc2 = HWACCMR0Disable(pVM);
78a072e1b56619e3230735ae073668311232ec94vboxsync AssertRC(rc2);
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync pVM->vmm.s.iLastGCRc = rc;
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync#ifdef VBOX_WITH_STATISTICS
78a072e1b56619e3230735ae073668311232ec94vboxsync vmmR0RecordRC(pVM, rc);
78a072e1b56619e3230735ae073668311232ec94vboxsync#endif
78a072e1b56619e3230735ae073668311232ec94vboxsync /* No special action required for external interrupts, just return. */
78a072e1b56619e3230735ae073668311232ec94vboxsync return rc;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Initialize the R0 part of a VM instance.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMR0_DO_VMMR0_INIT:
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync int rc = VMMR0Init(pVM, (unsigned)(uintptr_t)pvArg);
78a072e1b56619e3230735ae073668311232ec94vboxsync ASMSetFlags(fFlags);
78a072e1b56619e3230735ae073668311232ec94vboxsync return rc;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Terminate the R0 part of a VM instance.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMR0_DO_VMMR0_TERM:
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
78a072e1b56619e3230735ae073668311232ec94vboxsync int rc = VMMR0Term(pVM);
78a072e1b56619e3230735ae073668311232ec94vboxsync ASMSetFlags(fFlags);
78a072e1b56619e3230735ae073668311232ec94vboxsync return rc;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * Setup the hardware accelerated raw-mode session.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMR0_DO_HWACC_SETUP_VM:
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
78a072e1b56619e3230735ae073668311232ec94vboxsync int rc = HWACCMR0SetupVMX(pVM);
78a072e1b56619e3230735ae073668311232ec94vboxsync ASMSetFlags(fFlags);
78a072e1b56619e3230735ae073668311232ec94vboxsync return rc;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync * Switch to GC to execute Hypervisor function.
0fd573f0c3cdeafdc08b5bf60275bc6b619942cbvboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMR0_DO_CALL_HYPERVISOR:
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync {
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync /* Safety precaution as VMX disables the switcher. */
b357ffdbc9fd30f5187620831737367bb1830fefvboxsync Assert(!pVM->vmm.s.fSwitcherDisabled);
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync if (pVM->vmm.s.fSwitcherDisabled)
78a072e1b56619e3230735ae073668311232ec94vboxsync return VERR_NOT_SUPPORTED;
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync RTCCUINTREG fFlags = ASMIntDisableFlags();
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync int rc = pVM->vmm.s.pfnR0HostToGuest(pVM);
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync ASMSetFlags(fFlags);
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync return rc;
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync }
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync#ifdef VBOX_WITH_INTERNAL_NETWORKING
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync /*
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync * Services.
319e4aeb44409b63822d495e4edb4cda8e1b158evboxsync */
0fd573f0c3cdeafdc08b5bf60275bc6b619942cbvboxsync case VMMR0_DO_INTNET_OPEN:
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync case VMMR0_DO_INTNET_IF_CLOSE:
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync case VMMR0_DO_INTNET_IF_GET_RING3_BUFFER:
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync case VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE:
b357ffdbc9fd30f5187620831737367bb1830fefvboxsync case VMMR0_DO_INTNET_IF_SEND:
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync case VMMR0_DO_INTNET_IF_WAIT:
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync {
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync /*
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync * Validate arguments a bit first.
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync */
319e4aeb44409b63822d495e4edb4cda8e1b158evboxsync if (!VALID_PTR(pvArg))
78a072e1b56619e3230735ae073668311232ec94vboxsync return VERR_INVALID_POINTER;
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync if (!VALID_PTR(pVM))
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync return VERR_INVALID_POINTER;
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync if (pVM->pVMR0 != pVM)
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync return VERR_INVALID_POINTER;
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync if (!VALID_PTR(pVM->pSession))
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync return VERR_INVALID_POINTER;
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync if (!g_pIntNet)
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync return VERR_FILE_NOT_FOUND; ///@todo fix this status code!
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync /*
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync * Unpack the arguments and call the service.
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync */
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync switch (uOperation)
8c9f8fda080b7e99f35ef4d2ab8ec632ad2a4068vboxsync {
0fd573f0c3cdeafdc08b5bf60275bc6b619942cbvboxsync case VMMR0_DO_INTNET_OPEN:
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync PINTNETOPENARGS pArgs = (PINTNETOPENARGS)pvArg;
78a072e1b56619e3230735ae073668311232ec94vboxsync return INTNETR0Open(g_pIntNet, pVM->pSession, &pArgs->szNetwork[0], pArgs->cbSend, pArgs->cbRecv, pArgs->fRestrictAccess, &pArgs->hIf);
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMR0_DO_INTNET_IF_CLOSE:
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync PINTNETIFCLOSEARGS pArgs = (PINTNETIFCLOSEARGS)pvArg;
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync return INTNETR0IfClose(g_pIntNet, pArgs->hIf);
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync }
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync case VMMR0_DO_INTNET_IF_GET_RING3_BUFFER:
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync {
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync PINTNETIFGETRING3BUFFERARGS pArgs = (PINTNETIFGETRING3BUFFERARGS)pvArg;
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync return INTNETR0IfGetRing3Buffer(g_pIntNet, pArgs->hIf, &pArgs->pRing3Buf);
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync }
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync case VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE:
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync PINTNETIFSETPROMISCUOUSMODEARGS pArgs = (PINTNETIFSETPROMISCUOUSMODEARGS)pvArg;
78a072e1b56619e3230735ae073668311232ec94vboxsync return INTNETR0IfSetPromiscuousMode(g_pIntNet, pArgs->hIf, pArgs->fPromiscuous);
78a072e1b56619e3230735ae073668311232ec94vboxsync }
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMR0_DO_INTNET_IF_SEND:
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync PINTNETIFSENDARGS pArgs = (PINTNETIFSENDARGS)pvArg;
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync return INTNETR0IfSend(g_pIntNet, pArgs->hIf, pArgs->pvFrame, pArgs->cbFrame);
78a072e1b56619e3230735ae073668311232ec94vboxsync }
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync case VMMR0_DO_INTNET_IF_WAIT:
3af289fb9126c91f28ede0dcb3429da0de12b94evboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync PINTNETIFWAITARGS pArgs = (PINTNETIFWAITARGS)pvArg;
eb563d667bee4ab4ac0ba8be38d68f911f1d53eavboxsync return INTNETR0IfWait(g_pIntNet, pArgs->hIf, pArgs->cMillies);
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync }
eb563d667bee4ab4ac0ba8be38d68f911f1d53eavboxsync
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync default:
eb563d667bee4ab4ac0ba8be38d68f911f1d53eavboxsync return VERR_NOT_SUPPORTED;
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync#endif /* VBOX_WITH_INTERNAL_NETWORKING */
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
78a072e1b56619e3230735ae073668311232ec94vboxsync * For profiling.
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync */
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync case VMMR0_DO_NOP:
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync return VINF_SUCCESS;
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync /*
168f0d5dcd9366f5e1c22fcc49f8dc5a20d4686evboxsync * For testing Ring-0 APIs invoked in this environment.
78a072e1b56619e3230735ae073668311232ec94vboxsync */
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync case VMMR0_DO_TESTS:
78a072e1b56619e3230735ae073668311232ec94vboxsync /** @todo make new test */
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync return VINF_SUCCESS;
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync default:
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync /*
36dd9dabf3f64468206cb74145b51245cf7fde54vboxsync * We're returning VERR_NOT_SUPPORT here so we've got something else
168f0d5dcd9366f5e1c22fcc49f8dc5a20d4686evboxsync * than -1 which the interrupt gate glue code might return.
6fd13c2e3e855d7f5a7147cb0414af050e1503e6vboxsync */
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync Log(("operation %#x is not supported\n", uOperation));
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync return VERR_NOT_SUPPORTED;
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync }
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync}
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync/**
78a072e1b56619e3230735ae073668311232ec94vboxsync * Internal R0 logger worker: Flush logger.
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync *
78a072e1b56619e3230735ae073668311232ec94vboxsync * @param pLogger The logger instance to flush.
78a072e1b56619e3230735ae073668311232ec94vboxsync * @remark This function must be exported!
78a072e1b56619e3230735ae073668311232ec94vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsyncVMMR0DECL(void) vmmR0LoggerFlush(PRTLOGGER pLogger)
78a072e1b56619e3230735ae073668311232ec94vboxsync{
78a072e1b56619e3230735ae073668311232ec94vboxsync /*
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync * Convert the pLogger into a VM handle and 'call' back to Ring-3.
78a072e1b56619e3230735ae073668311232ec94vboxsync * (This is a bit paranoid code.)
78a072e1b56619e3230735ae073668311232ec94vboxsync */
f06e830c9fdbc3d9e89867d4429404c5446bc513vboxsync PVMMR0LOGGER pR0Logger = (PVMMR0LOGGER)((uintptr_t)pLogger - RT_OFFSETOF(VMMR0LOGGER, Logger));
78a072e1b56619e3230735ae073668311232ec94vboxsync if ( !VALID_PTR(pR0Logger)
78a072e1b56619e3230735ae073668311232ec94vboxsync || !VALID_PTR(pR0Logger + 1)
78a072e1b56619e3230735ae073668311232ec94vboxsync || !VALID_PTR(pLogger)
78a072e1b56619e3230735ae073668311232ec94vboxsync || pLogger->u32Magic != RTLOGGER_MAGIC)
c3d2b15ad840b405062f4c2c6b127d6fc107c7b2vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync LogCom(("vmmR0LoggerFlush: pLogger=%p!\n", pLogger));
78a072e1b56619e3230735ae073668311232ec94vboxsync return;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync PVM pVM = pR0Logger->pVM;
78a072e1b56619e3230735ae073668311232ec94vboxsync if ( !VALID_PTR(pVM)
78a072e1b56619e3230735ae073668311232ec94vboxsync || pVM->pVMHC != pVM)
78a072e1b56619e3230735ae073668311232ec94vboxsync {
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync LogCom(("vmmR0LoggerFlush: pVM=%p! pLogger=%p\n", pVM, pLogger));
78a072e1b56619e3230735ae073668311232ec94vboxsync return;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
168f0d5dcd9366f5e1c22fcc49f8dc5a20d4686evboxsync
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync /*
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync * Check that the jump buffer is armed.
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsync#ifdef __X86__
78a072e1b56619e3230735ae073668311232ec94vboxsync if (!pVM->vmm.s.CallHostR0JmpBuf.eip)
78a072e1b56619e3230735ae073668311232ec94vboxsync#else
78a072e1b56619e3230735ae073668311232ec94vboxsync if (!pVM->vmm.s.CallHostR0JmpBuf.rip)
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync#endif
5142b6456c5cec38e0ee291e235201d4ac73f10bvboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync LogCom(("vmmR0LoggerFlush: Jump buffer isn't armed!\n"));
78a072e1b56619e3230735ae073668311232ec94vboxsync pLogger->offScratch = 0;
78a072e1b56619e3230735ae073668311232ec94vboxsync return;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync VMMR0CallHost(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
78a072e1b56619e3230735ae073668311232ec94vboxsync}
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsyncvoid R0LogFlush()
78a072e1b56619e3230735ae073668311232ec94vboxsync{
85668909c68b5d0e67c89d6042535b41c4bffeccvboxsync vmmR0LoggerFlush(RTLogDefaultInstance());
85668909c68b5d0e67c89d6042535b41c4bffeccvboxsync}
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync#ifdef DEBUG_NO_RING0_ASSERTIONS
78a072e1b56619e3230735ae073668311232ec94vboxsync/**
034b3d77b1a08b77b1fa9bfd7489997421713f15vboxsync * Check if we really want to hit a breakpoint.
034b3d77b1a08b77b1fa9bfd7489997421713f15vboxsync * Can jump back to ring-3 when the longjmp is armed.
034b3d77b1a08b77b1fa9bfd7489997421713f15vboxsync */
78a072e1b56619e3230735ae073668311232ec94vboxsyncDECLEXPORT(bool) RTCALL RTAssertDoBreakpoint()
78a072e1b56619e3230735ae073668311232ec94vboxsync{
78a072e1b56619e3230735ae073668311232ec94vboxsync if (g_pVMAssert)
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync g_pVMAssert->vmm.s.enmCallHostOperation = VMMCALLHOST_VMM_LOGGER_FLUSH;
78a072e1b56619e3230735ae073668311232ec94vboxsync g_pVMAssert->vmm.s.u64CallHostArg = 0;
78a072e1b56619e3230735ae073668311232ec94vboxsync g_pVMAssert->vmm.s.rcCallHost = VERR_INTERNAL_ERROR;
78a072e1b56619e3230735ae073668311232ec94vboxsync int rc = vmmR0CallHostLongJmp(&g_pVMAssert->vmm.s.CallHostR0JmpBuf, VERR_INTERNAL_ERROR);
40fa6228bd9ab763bc67b51fe6290802e954eb8cvboxsync if (rc == VINF_SUCCESS)
78a072e1b56619e3230735ae073668311232ec94vboxsync rc = g_pVMAssert->vmm.s.rcCallHost;
78a072e1b56619e3230735ae073668311232ec94vboxsync }
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync return true;
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync}
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
cc260ed3418d1fd2771d0395f818f76808b60238vboxsync#undef LOG_GROUP
78a072e1b56619e3230735ae073668311232ec94vboxsync#define LOG_GROUP LOG_GROUP_EM
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync/** Runtime assert implementation for Native Win32 Ring-0. */
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsyncDECLEXPORT(void) RTCALL AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
78a072e1b56619e3230735ae073668311232ec94vboxsync{
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync Log(("\n!!R0-Assertion Failed!!\n"
223d0cc6ed8bf5767cb97c734684460b8eae31a8vboxsync "Expression: %s\n"
78a072e1b56619e3230735ae073668311232ec94vboxsync "Location : %s(%d) %s\n",
78a072e1b56619e3230735ae073668311232ec94vboxsync pszExpr, pszFile, uLine, pszFunction));
78a072e1b56619e3230735ae073668311232ec94vboxsync}
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync/**
78a072e1b56619e3230735ae073668311232ec94vboxsync * Callback for RTLogFormatV which writes to the com port.
37320c09d54b322461eb9833e3528aee029431e7vboxsync * See PFNLOGOUTPUT() for details.
37320c09d54b322461eb9833e3528aee029431e7vboxsync */
37320c09d54b322461eb9833e3528aee029431e7vboxsyncstatic DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars)
5f41c5732fa948e5fa142eb3997465c540574f84vboxsync{
6fd13c2e3e855d7f5a7147cb0414af050e1503e6vboxsync for (size_t i=0;i<cbChars;i++)
37320c09d54b322461eb9833e3528aee029431e7vboxsync Log(("%c", pachChars[i]));
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync return cbChars;
78a072e1b56619e3230735ae073668311232ec94vboxsync}
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsyncDECLEXPORT(void) RTCALL AssertMsg2(const char *pszFormat, ...)
78a072e1b56619e3230735ae073668311232ec94vboxsync{
223d0cc6ed8bf5767cb97c734684460b8eae31a8vboxsync PRTLOGGER pLog = RTLogDefaultInstance();
b0cec57d51e48736a3303366c728c3f025e8e81bvboxsync if (pLog)
78a072e1b56619e3230735ae073668311232ec94vboxsync {
78a072e1b56619e3230735ae073668311232ec94vboxsync va_list args;
be603ce3cb13b5ee7f4c3d85ea27ff41ac294535vboxsync
be603ce3cb13b5ee7f4c3d85ea27ff41ac294535vboxsync va_start(args, pszFormat);
be603ce3cb13b5ee7f4c3d85ea27ff41ac294535vboxsync RTLogFormatV(rtLogOutput, pLog, pszFormat, args);
be603ce3cb13b5ee7f4c3d85ea27ff41ac294535vboxsync va_end(args);
78a072e1b56619e3230735ae073668311232ec94vboxsync R0LogFlush();
78a072e1b56619e3230735ae073668311232ec94vboxsync }
223d0cc6ed8bf5767cb97c734684460b8eae31a8vboxsync}
223d0cc6ed8bf5767cb97c734684460b8eae31a8vboxsync
223d0cc6ed8bf5767cb97c734684460b8eae31a8vboxsync#endif
223d0cc6ed8bf5767cb97c734684460b8eae31a8vboxsync