summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/VMMRC/SELMRC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/VMM/VMMRC/SELMRC.cpp')
-rw-r--r--src/VBox/VMM/VMMRC/SELMRC.cpp42
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