EMRaw.cpp revision 7a896688c49bde3fa1490e7ebb321ac51b6ad29d
2N/A * available from http://www.virtualbox.org. This file is free software;
2N/A#ifdef VBOX_WITH_REM
2N/A#include "EMInternal.h"
2N/A#include "VMMTracing.h"
2N/ADECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC = VINF_SUCCESS);
2N/A#define EMHANDLERC_WITH_PATM
2N/A#include "EMHandleRCTmpl.h"
2N/A#ifdef VBOX_WITH_STATISTICS
2N/A STAM_REG(pVM, &pRec->Counter, STAMTYPE_COUNTER, szCliStatName, STAMUNIT_OCCURENCES, "Number of times cli was executed.");
2N/A Log(("emR3RawResumeHyper: cs:eip=%RTsel:%RGr efl=%RGr\n", pCtx->cs.Sel, pCtx->eip, pCtx->eflags));
2N/A Log(("emR3RawResumeHyper: cs:eip=%RTsel:%RGr efl=%RGr - returned from GC with rc=%Rrc\n", pCtx->cs.Sel, pCtx->eip, pCtx->eflags, rc));
return rc;
int rc;
#ifndef DEBUG_sandervl
Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr\n", fGuest ? CPUMGetGuestCS(pVCpu) : CPUMGetHyperCS(pVCpu),
fGuest ? CPUMGetGuestEIP(pVCpu) : CPUMGetHyperEIP(pVCpu), fGuest ? CPUMGetGuestEFlags(pVCpu) : CPUMGetHyperEFlags(pVCpu)));
if (fGuest)
return rc;
#ifndef DEBUG_sandervl
Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr - GC rc %Rrc\n", fGuest ? CPUMGetGuestCS(pVCpu) : CPUMGetHyperCS(pVCpu),
fGuest ? CPUMGetGuestEIP(pVCpu) : CPUMGetHyperEIP(pVCpu), fGuest ? CPUMGetGuestEFlags(pVCpu) : CPUMGetHyperEFlags(pVCpu), rc));
if (fGuest)
return rc;
#ifdef DEBUG
return rc;
#ifdef LOG_ENABLED
int rc;
#ifdef LOG_ENABLED
if (pszPrefix)
switch (rc)
case VINF_SUCCESS:
return VINF_EM_RESCHEDULE_REM;
case VINF_PATCH_EMULATE_INSTR:
case VERR_PATCH_DISABLED:
return VINF_EM_RESCHEDULE_REM;
case VINF_PATCH_CONTINUE:
return VINF_SUCCESS;
return VERR_IPE_UNEXPECTED_STATUS;
#ifdef VBOX_WITH_REM
return rc;
#ifdef LOG_ENABLED
/** @todo probably we should fall back to the recompiler; otherwise we'll go back and forth between HC & GC
case OP_IN:
case OP_OUT:
case OP_INSB:
case OP_INSWD:
case OP_OUTSB:
case OP_OUTSWD:
AssertMsg(rcStrict == VINF_EM_RAW_EMULATE_INSTR || rcStrict == VINF_EM_RESCHEDULE_REM, ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
return rc;
if ( uCpl == 0
Log(("emR3RawHandleRC: recheck gate %x -> valid=%d\n", u8TrapNo, TRPMR3GetGuestTrapHandler(pVM, u8TrapNo) != TRPM_INVALID_HANDLER));
return VINF_EM_RESCHEDULE_RAW;
rc = VBOXSTRICTRC_TODO(EMInterpretInstructionDisasState(pVCpu, &cpu, CPUMCTX2CORE(pCtx), 0, EMCODETYPE_SUPERVISOR));
return rc;
#ifdef LOG_ENABLED
Log(("emR3RawGuestTrap: cs:eip=%04x:%08x: trap=%02x err=%08x cr2=%08x cr0=%08x%s: Phys=%RGp fFlags=%08llx %s %s %s%s rc2=%d\n",
return VINF_EM_RESCHEDULE_REM;
int rc;
return VINF_EM_RESCHEDULE_RAW;
#ifdef VBOX_WITH_STATISTICS
case OP_SYSENTER:
case OP_SYSEXIT:
case OP_SYSCALL:
case OP_SYSRET:
int rc;
uCR2 = 0;
uErrorCode = 0;
uCR2 = 0;
uErrorCode = 0;
return rc;
#ifdef LOG_ENABLED
Log(("Patch code: IRET->VM stack frame: return address %04X:%08RX32 eflags=%08x ss:esp=%04X:%08RX32\n", selCS, eip, uEFlags, selSS, esp));
Log(("Patch code: IRET->VM stack frame: DS=%04X ES=%04X FS=%04X GS=%04X\n", selDS, selES, selFS, selGS));
Log(("Patch code: IRET stack frame: return address %04X:%08RX32 eflags=%08x ss:esp=%04X:%08RX32\n", selCS, eip, uEFlags, selSS, esp));
Log(("Patch code: IRET stack frame: return address %04X:%08RX32 eflags=%08x\n", selCS, eip, uEFlags));
switch (rc)
case VINF_SUCCESS:
return VINF_EM_RESCHEDULE_REM;
case VINF_PATCH_EMULATE_INSTR:
case VERR_PATCH_DISABLED:
return VINF_EM_RESCHEDULE_REM;
case VINF_PATCH_CONTINUE:
return VINF_SUCCESS;
return VERR_IPE_UNEXPECTED_STATUS;
return VINF_SUCCESS;
#ifdef LOG_ENABLED
AssertMsgFailed(("FATAL ERROR: executing random instruction inside generated patch jump %08X\n", pCtx->eip));
return VERR_EM_RAW_PATCH_CONFLICT;
#ifdef LOG_ENABLED
return VINF_SUCCESS;
#ifdef LOG_ENABLED
int rc;
#ifdef VBOX_WITH_STATISTICS
case OP_INVLPG:
case OP_IRET:
case OP_CLI:
case OP_STI:
case OP_INSB:
case OP_INSWD:
case OP_IN:
case OP_OUTSB:
case OP_OUTSWD:
case OP_OUT:
case OP_MOV_CR:
case OP_MOV_DR:
case OP_LLDT:
case OP_LIDT:
case OP_LGDT:
case OP_SYSENTER:
case OP_SYSEXIT:
case OP_SYSCALL:
case OP_SYSRET:
case OP_HLT:
case OP_CLI:
case OP_STI:
return VINF_SUCCESS;
case OP_HLT:
AssertReleaseMsg(pOrgInstrGC && enmState != PATMTRANS_OVERWRITTEN, ("Unable to translate instruction address at %08RX32\n", pCtx->eip));
case OP_MOV_CR:
case OP_MOV_DR:
#ifdef LOG_ENABLED
rc = VBOXSTRICTRC_TODO(EMInterpretInstructionDisasState(pVCpu, &Cpu, CPUMCTX2CORE(pCtx), 0, EMCODETYPE_SUPERVISOR));
Log(("Force recompiler switch due to cr0 (%RGp) update rip=%RGv -> %RGv (enmState=%d)\n", pCtx->cr0, pCtx->rip, pOrgInstrGC, enmState));
AssertReleaseMsg(pOrgInstrGC && enmState != PATMTRANS_OVERWRITTEN, ("Unable to translate instruction address at %RGv\n", (RTGCPTR)pCtx->rip));
return VINF_EM_RESCHEDULE;
switch (rc)
case VINF_EM_RESCHEDULE:
case VINF_EM_RESCHEDULE_REM:
return rc;
return rc;
return rc;
int rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
return rc;
return rc;
return rc;
int rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
return rc;
return rc;
rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
return rc;
return rc;
return VINF_EM_NO_MEMORY;
return VINF_SUCCESS;
*pfFFDone = false;
#ifdef VBOX_STRICT
# ifdef VBOX_WITH_REM
Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0);
#ifdef LOG_ENABLED
Log(("RV86: %04X:%08X IF=%d VMFlags=%x\n", pCtx->cs.Sel, pCtx->eip, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags));
Log(("RR0: %08X ESP=%08X IF=%d VMFlags=%x PIF=%d CPL=%d (Scanned=%d)\n", pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags, pGCState->fPIF, (pCtx->ss.Sel & X86_SEL_RPL), fCSAMScanned));
Log(("RR3: %08X ESP=%08X IF=%d VMFlags=%x\n", pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags));
LogFlow(("RR0-E: %08X ESP=%08X IF=%d VMFlags=%x PIF=%d CPL=%d\n", pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags, pGCState->fPIF, (pCtx->ss.Sel & X86_SEL_RPL)));
#ifdef VBOX_STRICT
if ( !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_SELM_SYNC_GDT) /* GDT implies TSS at the moment. */
switch (rc)
case VINF_SUCCESS:
case VINF_EM_RAW_INTERRUPT:
case VINF_PATM_PATCH_TRAP_PF:
case VINF_PATM_PATCH_TRAP_GP:
case VINF_PATM_PATCH_INT3:
case VINF_EM_RAW_GUEST_TRAP:
case VINF_EM_RESCHEDULE_RAW:
LogIt(NULL, 0, LOG_GROUP_PATM, ("Patch code interrupted at %RRv for reason %Rrc\n", (RTRCPTR)CPUMGetGuestEIP(pVCpu), rc));
#ifdef VBOX_HIGH_RES_TIMERS_HACK
*pfFFDone = true;
return rc;