diff options
Diffstat (limited to 'src/VBox/VMM/VMMRC/SELMRC.cpp')
| -rw-r--r-- | src/VBox/VMM/VMMRC/SELMRC.cpp | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/VBox/VMM/VMMRC/SELMRC.cpp b/src/VBox/VMM/VMMRC/SELMRC.cpp index 2fd3e7af..65367f39 100644 --- a/src/VBox/VMM/VMMRC/SELMRC.cpp +++ b/src/VBox/VMM/VMMRC/SELMRC.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -34,6 +34,8 @@ #include <iprt/assert.h> #include <iprt/asm.h> +#include "SELMInline.h" + /******************************************************************************* * Global Variables * @@ -44,6 +46,7 @@ static char const g_aszSRegNms[X86_SREG_COUNT][4] = { "ES", "CS", "SS", "DS", "F #endif +#ifdef SELM_TRACK_GUEST_GDT_CHANGES /** * Synchronizes one GDT entry (guest -> shadow). * @@ -122,7 +125,7 @@ static VBOXSTRICTRC selmRCSyncGDTEntry(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegF /* * Convert the guest selector to a shadow selector and update the shadow GDT. */ - selmGuestToShadowDesc(&Desc); + selmGuestToShadowDesc(pVM, &Desc); PX86DESC pShwDescr = &pVM->selm.s.paGdtRC[iGDTEntry]; //Log(("O: base=%08X limit=%08X attr=%04X\n", X86DESC_BASE(*pShwDescr)), X86DESC_LIMIT(*pShwDescr), (pShwDescr->au32[1] >> 8) & 0xFFFF )); //Log(("N: base=%08X limit=%08X attr=%04X\n", X86DESC_BASE(Desc)), X86DESC_LIMIT(Desc), (Desc.au32[1] >> 8) & 0xFFFF )); @@ -145,7 +148,8 @@ static VBOXSTRICTRC selmRCSyncGDTEntry(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegF Log(("GDT write to selector in %s register %04X (now stale)\n", g_aszSRegNms[iSReg], paSReg[iSReg].Sel)); paSReg[iSReg].fFlags |= CPUMSELREG_FLAGS_STALE; VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3); /* paranoia */ - rcStrict = VINF_EM_RESCHEDULE_REM; + /* rcStrict = VINF_EM_RESCHEDULE_REM; - bad idea if we're in a patch. */ + rcStrict = VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT; } else if (paSReg[iSReg].fFlags & CPUMSELREG_FLAGS_STALE) { @@ -284,6 +288,9 @@ VMMRCDECL(int) selmRCGuestGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTX if (rc2 == VINF_SUCCESS || rc2 == VINF_EM_RESCHEDULE_REM) { + /* VINF_EM_RESCHEDULE_REM - bad idea if we're in a patch. */ + if (rc2 == VINF_EM_RESCHEDULE_REM) + rc = VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT; STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestGDTHandled); return rc; } @@ -305,8 +312,10 @@ VMMRCDECL(int) selmRCGuestGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTX STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestGDTUnhandled); return rc; } +#endif /* SELM_TRACK_GUEST_GDT_CHANGES */ +#ifdef SELM_TRACK_GUEST_LDT_CHANGES /** * \#PF Virtual Handler callback for Guest write access to the Guest's own LDT. * @@ -329,8 +338,10 @@ VMMRCDECL(int) selmRCGuestLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTX STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestLDT); return VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT; } +#endif +#ifdef SELM_TRACK_GUEST_TSS_CHANGES /** * Read wrapper used by selmRCGuestTSSWriteHandler. * @returns VBox status code (appropriate for trap handling and GC return). @@ -381,7 +392,8 @@ VMMRCDECL(int) selmRCGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTX */ uint32_t cb; int rc = EMInterpretInstructionEx(pVCpu, pRegFrame, (RTGCPTR)(RTRCUINTPTR)pvFault, &cb); - if (RT_SUCCESS(rc) && cb) + if ( RT_SUCCESS(rc) + && cb) { rc = VINF_SUCCESS; @@ -402,6 +414,21 @@ VMMRCDECL(int) selmRCGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTX pVM->selm.s.Tss.ss1 = pGuestTss->ss0 | 1; STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSHandledChanged); } +#ifdef VBOX_WITH_RAW_RING1 + else if ( EMIsRawRing1Enabled(pVM) + && PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS(&pGuestTss->padding_ss1) + && PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS((uint8_t *)pGuestTss + offRange) + && ( pGuestTss->esp1 != pVM->selm.s.Tss.esp2 + || pGuestTss->ss1 != ((pVM->selm.s.Tss.ss2 & ~2) | 1)) /* undo raw-r1 */ + ) + { + Log(("selmRCGuestTSSWriteHandler: R1 stack: %RTsel:%RGv -> %RTsel:%RGv\n", + (RTSEL)((pVM->selm.s.Tss.ss2 & ~2) | 1), (RTGCPTR)pVM->selm.s.Tss.esp2, (RTSEL)pGuestTss->ss1, (RTGCPTR)pGuestTss->esp1)); + pVM->selm.s.Tss.esp2 = pGuestTss->esp1; + pVM->selm.s.Tss.ss2 = (pGuestTss->ss1 & ~1) | 2; + STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSHandledChanged); + } +#endif /* Handle misaligned TSS in a safe manner (just in case). */ else if ( offRange >= RT_UOFFSETOF(VBOXTSS, esp0) && offRange < RT_UOFFSETOF(VBOXTSS, padding_ss0)) @@ -491,8 +518,10 @@ VMMRCDECL(int) selmRCGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTX } return rc; } +#endif /* SELM_TRACK_GUEST_TSS_CHANGES */ +#ifdef SELM_TRACK_SHADOW_GDT_CHANGES /** * \#PF Virtual Handler callback for Guest write access to the VBox shadow GDT. * @@ -511,8 +540,10 @@ VMMRCDECL(int) selmRCShadowGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCT NOREF(pVM); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); return VERR_SELM_SHADOW_GDT_WRITE; } +#endif +#ifdef SELM_TRACK_SHADOW_LDT_CHANGES /** * \#PF Virtual Handler callback for Guest write access to the VBox shadow LDT. * @@ -532,8 +563,10 @@ VMMRCDECL(int) selmRCShadowLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCT NOREF(pVM); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); return VERR_SELM_SHADOW_LDT_WRITE; } +#endif +#ifdef SELM_TRACK_SHADOW_TSS_CHANGES /** * \#PF Virtual Handler callback for Guest write access to the VBox shadow TSS. * @@ -552,4 +585,5 @@ VMMRCDECL(int) selmRCShadowTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCT NOREF(pVM); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); return VERR_SELM_SHADOW_TSS_WRITE; } +#endif |
