VMMGC.cpp revision 3ec2b25f77f15eeb71c2ad7569854e5cce4280a3
a299266cddc1ae14d76d725a660bb278816bc151vboxsync/* $Id$ */
a299266cddc1ae14d76d725a660bb278816bc151vboxsync/** @file
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * VMM - Raw-mode Context.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync */
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync/*
e99772f9bf09219c532812c859fbeea513c67e65vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync *
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * available from http://www.virtualbox.org. This file is free software;
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * General Public License (GPL) as published by the Free Software
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync *
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * additional information or have any questions.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync */
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync/*******************************************************************************
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync* Header Files *
a299266cddc1ae14d76d725a660bb278816bc151vboxsync*******************************************************************************/
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#define LOG_GROUP LOG_GROUP_VMM
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include <VBox/vmm.h>
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include <VBox/trpm.h>
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include <VBox/pgm.h>
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include "VMMInternal.h"
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include <VBox/vm.h>
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include <VBox/sup.h>
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync#include <VBox/err.h>
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include <VBox/log.h>
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include <iprt/asm.h>
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#include <iprt/assert.h>
e99772f9bf09219c532812c859fbeea513c67e65vboxsync#include <iprt/initterm.h>
739c9e0e5fccb99475b8202ead8fc5665b2fa64cvboxsync
e99772f9bf09219c532812c859fbeea513c67e65vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync/*******************************************************************************
a299266cddc1ae14d76d725a660bb278816bc151vboxsync* Global Variables *
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync*******************************************************************************/
a299266cddc1ae14d76d725a660bb278816bc151vboxsync/** Default logger instance. */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsyncextern "C" DECLIMPORT(RTLOGGERRC) g_Logger;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsyncextern "C" DECLIMPORT(RTLOGGERRC) g_RelLogger;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync/*******************************************************************************
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync* Internal Functions *
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync*******************************************************************************/
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsyncstatic int vmmGCTest(PVM pVM, unsigned uOperation, unsigned uArg);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsyncstatic DECLCALLBACK(int) vmmGCTestTmpPFHandler(PVM pVM, PCPUMCTXCORE pRegFrame);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsyncstatic DECLCALLBACK(int) vmmGCTestTmpPFHandlerCorruptFS(PVM pVM, PCPUMCTXCORE pRegFrame);
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync/**
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync * The GC entry point.
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync *
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync * @returns VBox status code.
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync * @param pVM The VM to operate on.
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync * @param uOperation Which operation to execute (VMMGCOPERATION).
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync * @param uArg Argument to that operation.
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync */
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsyncVMMRCDECL(int) VMMGCEntry(PVM pVM, unsigned uOperation, unsigned uArg, ...)
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync{
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync /* todo */
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync switch (uOperation)
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync {
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync /*
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync * Init RC modules.
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync */
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync case VMMGC_DO_VMMGC_INIT:
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync {
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync /*
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync * Validate the svn revision (uArg).
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync */
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync if (uArg != VMMGetSvnRev())
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync return VERR_VERSION_MISMATCH;
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync /*
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync * Initialize the runtime.
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync * (The program timestamp is found in the elipsis.)
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync */
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync va_list va;
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync va_start(va, uArg);
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync uint64_t u64TS = va_arg(va, uint64_t);
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync va_end(va);
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync int rc = RTRCInit(u64TS);
a299266cddc1ae14d76d725a660bb278816bc151vboxsync Log(("VMMGCEntry: VMMGC_DO_VMMGC_INIT - uArg=%u (svn revision) u64TS=%RX64; rc=%Rrc\n", uArg, u64TS, rc));
a299266cddc1ae14d76d725a660bb278816bc151vboxsync AssertRCReturn(rc, rc);
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync rc = PGMRegisterStringFormatTypes();
a299266cddc1ae14d76d725a660bb278816bc151vboxsync AssertRCReturn(rc, rc);
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync return VINF_SUCCESS;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync /*
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync * Testcase which is used to test interrupt forwarding.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * It spins for a while with interrupts enabled.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync */
a299266cddc1ae14d76d725a660bb278816bc151vboxsync case VMMGC_DO_TESTCASE_HYPER_INTERRUPT:
a299266cddc1ae14d76d725a660bb278816bc151vboxsync {
a299266cddc1ae14d76d725a660bb278816bc151vboxsync uint32_t volatile i = 0;
a299266cddc1ae14d76d725a660bb278816bc151vboxsync ASMIntEnable();
a299266cddc1ae14d76d725a660bb278816bc151vboxsync while (i < _2G32)
a299266cddc1ae14d76d725a660bb278816bc151vboxsync i++;
a299266cddc1ae14d76d725a660bb278816bc151vboxsync ASMIntDisable();
a299266cddc1ae14d76d725a660bb278816bc151vboxsync return 0;
a299266cddc1ae14d76d725a660bb278816bc151vboxsync }
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync /*
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * Testcase which simply returns, this is used for
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * profiling of the switcher.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync */
a299266cddc1ae14d76d725a660bb278816bc151vboxsync case VMMGC_DO_TESTCASE_NOP:
a299266cddc1ae14d76d725a660bb278816bc151vboxsync return 0;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync /*
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Testcase executes a privileged instruction to force a world switch. (in both SVM & VMX)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync case VMMGC_DO_TESTCASE_HWACCM_NOP:
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync ASMRdMsr_Low(MSR_IA32_SYSENTER_CS);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync return 0;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync /*
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Delay for ~100us.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync case VMMGC_DO_TESTCASE_INTERRUPT_MASKING:
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync {
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync uint64_t u64MaxTicks = (SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage) != ~(uint64_t)0
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync ? SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage)
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync : _2G)
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync / 10000;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync uint64_t u64StartTSC = ASMReadTSC();
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync uint64_t u64TicksNow;
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync uint32_t volatile i = 0;
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync do
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync {
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* waste some time and protect against getting stuck. */
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync for (uint32_t volatile j = 0; j < 1000; j++, i++)
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync if (i > _2G32)
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync return VERR_GENERAL_FAILURE;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync /* check if we're done.*/
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync u64TicksNow = ASMReadTSC() - u64StartTSC;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync } while (u64TicksNow < u64MaxTicks);
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync return VINF_SUCCESS;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync /*
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Trap testcases and unknown operations.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync default:
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync if ( uOperation >= VMMGC_DO_TESTCASE_TRAP_FIRST
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync && uOperation < VMMGC_DO_TESTCASE_TRAP_LAST)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync return vmmGCTest(pVM, uOperation, uArg);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync return VERR_INVALID_PARAMETER;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync}
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync/**
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Internal RC logger worker: Flush logger.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync *
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @returns VINF_SUCCESS.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @param pLogger The logger instance to flush.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @remark This function must be exported!
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsyncVMMRCDECL(int) vmmGCLoggerFlush(PRTLOGGERRC pLogger)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync{
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync PVM pVM = &g_VM;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync NOREF(pLogger);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync if (pVM->vmm.s.fRCLoggerFlushingDisabled)
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync return VINF_SUCCESS; /* fail quietly. */
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync return VMMRZCallRing3NoCpu(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync}
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync/**
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync * Flush logger if almost full.
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync *
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync * @param pVM The VM handle.
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsyncVMMRCDECL(void) VMMGCLogFlushIfFull(PVM pVM)
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync{
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync if ( pVM->vmm.s.pRCLoggerRC
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync && pVM->vmm.s.pRCLoggerRC->offScratch >= (sizeof(pVM->vmm.s.pRCLoggerRC->achScratch)*3/4))
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync {
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync if (pVM->vmm.s.fRCLoggerFlushingDisabled)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync return; /* fail quietly. */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync VMMRZCallRing3NoCpu(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync}
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync/**
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Switches from guest context to host context.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync *
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @param pVM The VM handle.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @param rc The status code.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsyncVMMRCDECL(void) VMMGCGuestToHost(PVM pVM, int rc)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync{
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync pVM->vmm.s.pfnGuestToHostRC(rc);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync}
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync/**
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Execute the trap testcase.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync *
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * There is some common code here, that's why we're collecting them
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * like this. Odd numbered variation (uArg) are executed with write
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * protection (WP) enabled.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync *
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @returns VINF_SUCCESS if it was a testcase setup up to continue and did so successfully.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @returns VERR_NOT_IMPLEMENTED if the testcase wasn't implemented.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @returns VERR_GENERAL_FAILURE if the testcase continued when it shouldn't.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync *
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @param pVM The VM handle.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @param uOperation The testcase.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @param uArg The variation. See function description for odd / even details.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync *
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @remark Careful with the trap 08 testcase and WP, it will tripple
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * fault the box if the TSS, the Trap8 TSS and the fault TSS
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * GDTE are in pages which are read-only.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * See bottom of SELMR3Init().
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
ad27e1d5e48ca41245120c331cc88b50464813cevboxsyncstatic int vmmGCTest(PVM pVM, unsigned uOperation, unsigned uArg)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync{
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync /*
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Set up the testcase.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync#if 0
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync switch (uOperation)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync {
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync default:
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync break;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync#endif
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync /*
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Enable WP if odd variation.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync if (uArg & 1)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync vmmGCEnableWP();
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync /*
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Execute the testcase.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync int rc = VERR_NOT_IMPLEMENTED;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync switch (uOperation)
a299266cddc1ae14d76d725a660bb278816bc151vboxsync {
a299266cddc1ae14d76d725a660bb278816bc151vboxsync //case VMMGC_DO_TESTCASE_TRAP_0:
a299266cddc1ae14d76d725a660bb278816bc151vboxsync //case VMMGC_DO_TESTCASE_TRAP_1:
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync //case VMMGC_DO_TESTCASE_TRAP_2:
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync case VMMGC_DO_TESTCASE_TRAP_3:
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync {
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync if (uArg <= 1)
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync rc = vmmGCTestTrap3();
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync break;
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync }
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync //case VMMGC_DO_TESTCASE_TRAP_4:
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync //case VMMGC_DO_TESTCASE_TRAP_5:
a299266cddc1ae14d76d725a660bb278816bc151vboxsync //case VMMGC_DO_TESTCASE_TRAP_6:
a299266cddc1ae14d76d725a660bb278816bc151vboxsync //case VMMGC_DO_TESTCASE_TRAP_7:
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync case VMMGC_DO_TESTCASE_TRAP_8:
a299266cddc1ae14d76d725a660bb278816bc151vboxsync {
a299266cddc1ae14d76d725a660bb278816bc151vboxsync#ifndef DEBUG_bird /** @todo dynamic check that this won't tripple fault... */
a299266cddc1ae14d76d725a660bb278816bc151vboxsync if (uArg & 1)
a299266cddc1ae14d76d725a660bb278816bc151vboxsync break;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync#endif
a299266cddc1ae14d76d725a660bb278816bc151vboxsync if (uArg <= 1)
a299266cddc1ae14d76d725a660bb278816bc151vboxsync rc = vmmGCTestTrap8();
a299266cddc1ae14d76d725a660bb278816bc151vboxsync break;
a299266cddc1ae14d76d725a660bb278816bc151vboxsync }
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync //VMMGC_DO_TESTCASE_TRAP_9,
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync //VMMGC_DO_TESTCASE_TRAP_0A,
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync //VMMGC_DO_TESTCASE_TRAP_0B,
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync //VMMGC_DO_TESTCASE_TRAP_0C,
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync case VMMGC_DO_TESTCASE_TRAP_0D:
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync {
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync if (uArg <= 1)
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync rc = vmmGCTestTrap0d();
b2c35a7024c4c308b429c81b203b3bcbd44ee60cvboxsync break;
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync }
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync case VMMGC_DO_TESTCASE_TRAP_0E:
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync {
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync if (uArg <= 1)
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync rc = vmmGCTestTrap0e();
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync else if (uArg == 2 || uArg == 4)
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync {
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync /*
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * Test the use of a temporary #PF handler.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync rc = TRPMGCSetTempHandler(pVM, X86_XCPT_PF, uArg != 4 ? vmmGCTestTmpPFHandler : vmmGCTestTmpPFHandlerCorruptFS);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync if (RT_SUCCESS(rc))
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync {
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync rc = vmmGCTestTrap0e();
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync /* in case it didn't fire. */
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync int rc2 = TRPMGCSetTempHandler(pVM, X86_XCPT_PF, NULL);
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync rc = rc2;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync break;
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync }
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync /*
4bcaf5d320bf0d88910212509c37bdd634e0879evboxsync * Re-enable WP.
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync */
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync if (uArg & 1)
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync vmmGCDisableWP();
cec3b04587a02f0dc7d0cc679e9a0de19b730e2cvboxsync
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync return rc;
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync}
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync/**
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync * Temporary #PF trap handler for the #PF test case.
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync *
e45e3ae4a834169539e689759ba6b3ac71bfe40fvboxsync * @returns VBox status code (appropriate for GC return).
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * In this context RT_SUCCESS means to restart the instruction.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @param pVM VM handle.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync * @param pRegFrame Trap register frame.
6578276195b5b6a53ef2fc44f96a3348c516d3f5vboxsync */
a299266cddc1ae14d76d725a660bb278816bc151vboxsyncstatic DECLCALLBACK(int) vmmGCTestTmpPFHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
a299266cddc1ae14d76d725a660bb278816bc151vboxsync{
a299266cddc1ae14d76d725a660bb278816bc151vboxsync if (pRegFrame->eip == (uintptr_t)vmmGCTestTrap0e_FaultEIP)
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync {
a299266cddc1ae14d76d725a660bb278816bc151vboxsync pRegFrame->eip = (uintptr_t)vmmGCTestTrap0e_ResumeEIP;
a299266cddc1ae14d76d725a660bb278816bc151vboxsync return VINF_SUCCESS;
a299266cddc1ae14d76d725a660bb278816bc151vboxsync }
a299266cddc1ae14d76d725a660bb278816bc151vboxsync return VERR_INTERNAL_ERROR;
a299266cddc1ae14d76d725a660bb278816bc151vboxsync}
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync
a299266cddc1ae14d76d725a660bb278816bc151vboxsync/**
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync * Temporary #PF trap handler for the #PF test case, this one messes up the fs selector.
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync *
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * @returns VBox status code (appropriate for GC return).
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * In this context RT_SUCCESS means to restart the instruction.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * @param pVM VM handle.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync * @param pRegFrame Trap register frame.
a299266cddc1ae14d76d725a660bb278816bc151vboxsync */
a299266cddc1ae14d76d725a660bb278816bc151vboxsyncstatic DECLCALLBACK(int) vmmGCTestTmpPFHandlerCorruptFS(PVM pVM, PCPUMCTXCORE pRegFrame)
a299266cddc1ae14d76d725a660bb278816bc151vboxsync{
a299266cddc1ae14d76d725a660bb278816bc151vboxsync int rc = vmmGCTestTmpPFHandler(pVM, pRegFrame);
a299266cddc1ae14d76d725a660bb278816bc151vboxsync pRegFrame->fs = 0x30;
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync return rc;
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync}
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync
4a4d802b46dfabbfd36e88822ff7b17421120469vboxsync