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