summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/VMM/VMMAll/IOMAllMMIO.cpp')
-rw-r--r--src/VBox/VMM/VMMAll/IOMAllMMIO.cpp373
1 files changed, 229 insertions, 144 deletions
diff --git a/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp b/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
index ba4133e6..32cc2360 100644
--- a/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
+++ b/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 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,7 +34,7 @@
#include "IOMInternal.h"
#include <VBox/vmm/vm.h>
#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
#include "IOMInline.h"
#include <VBox/dis.h>
@@ -77,7 +77,7 @@ static const unsigned g_aSize2Shift[] =
/**
* Deals with complicated MMIO writes.
*
- * Complicatd means unaligned or non-dword/qword align accesses depending on
+ * Complicated means unaligned or non-dword/qword sized accesses depending on
* the MMIO region's access mode flags.
*
* @returns Strict VBox status code. Any EM scheduling status code,
@@ -97,7 +97,8 @@ static VBOXSTRICTRC iomMMIODoComplicatedWrite(PVM pVM, PIOMMMIORANGE pRange, RTG
VERR_IOM_MMIO_IPE_1);
AssertReturn(cbValue != 0 && cbValue <= 16, VERR_IOM_MMIO_IPE_2);
RTGCPHYS const GCPhysStart = GCPhys; NOREF(GCPhysStart);
- bool const fReadMissing = (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) >= IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING;
+ bool const fReadMissing = (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING
+ || (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING;
/*
* Do debug stop if requested.
@@ -117,6 +118,19 @@ static VBOXSTRICTRC iomMMIODoComplicatedWrite(PVM pVM, PIOMMMIORANGE pRange, RTG
}
#endif
+ /*
+ * Check if we should ignore the write.
+ */
+ if ((pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_ONLY_DWORD)
+ {
+ Assert(cbValue != 4 || (GCPhys & 3));
+ return VINF_SUCCESS;
+ }
+ if ((pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD)
+ {
+ Assert((cbValue != 4 && cbValue != 8) || (GCPhys & (cbValue - 1)));
+ return VINF_SUCCESS;
+ }
/*
* Split and conquer.
@@ -150,8 +164,12 @@ static VBOXSTRICTRC iomMMIODoComplicatedWrite(PVM pVM, PIOMMMIORANGE pRange, RTG
case VINF_IOM_R3_MMIO_READ_WRITE:
case VINF_IOM_R3_MMIO_WRITE:
/** @todo What if we've split a transfer and already read
- * something? Since reads can have sideeffects we could be
- * kind of screwed here... */
+ * something? Since writes generally have sideeffects we
+ * could be kind of screwed here...
+ *
+ * Fix: Save the current state and resume it in ring-3. Requires EM to not go
+ * to REM for MMIO accesses (like may currently do). */
+
LogFlow(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [read]\n", GCPhys, GCPhysStart, cbValue, rc2));
return rc2;
default:
@@ -197,7 +215,7 @@ static VBOXSTRICTRC iomMMIODoComplicatedWrite(PVM pVM, PIOMMMIORANGE pRange, RTG
if (offAccess)
{
u32GivenValue <<= offAccess * 8;
- u32GivenMask <<= offAccess * 8;
+ u32GivenMask <<= offAccess * 8;
}
uint32_t u32Value = (u32MissingValue & ~u32GivenMask)
@@ -217,7 +235,10 @@ static VBOXSTRICTRC iomMMIODoComplicatedWrite(PVM pVM, PIOMMMIORANGE pRange, RTG
case VINF_IOM_R3_MMIO_WRITE:
/** @todo What if we've split a transfer and already read
* something? Since reads can have sideeffects we could be
- * kind of screwed here... */
+ * kind of screwed here...
+ *
+ * Fix: Save the current state and resume it in ring-3. Requires EM to not go
+ * to REM for MMIO accesses (like may currently do). */
LogFlow(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [write]\n", GCPhys, GCPhysStart, cbValue, rc2));
return rc2;
default:
@@ -252,20 +273,28 @@ static VBOXSTRICTRC iomMMIODoComplicatedWrite(PVM pVM, PIOMMMIORANGE pRange, RTG
* Wrapper which does the write and updates range statistics when such are enabled.
* @warning RT_SUCCESS(rc=VINF_IOM_R3_MMIO_WRITE) is TRUE!
*/
-static int iomMMIODoWrite(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault, const void *pvData, unsigned cb)
+static int iomMMIODoWrite(PVM pVM, PVMCPU pVCpu, PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault, const void *pvData, unsigned cb)
{
#ifdef VBOX_WITH_STATISTICS
- PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhysFault, pRange);
- Assert(pStats);
+ int rcSem = IOM_LOCK_SHARED(pVM);
+ if (rcSem == VERR_SEM_BUSY)
+ return VINF_IOM_R3_MMIO_WRITE;
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhysFault, pRange);
+ if (!pStats)
+# ifdef IN_RING3
+ return VERR_NO_MEMORY;
+# else
+ return VINF_IOM_R3_MMIO_WRITE;
+# endif
+ STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
#endif
- STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
VBOXSTRICTRC rc;
if (RT_LIKELY(pRange->CTX_SUFF(pfnWriteCallback)))
{
if ( (cb == 4 && !(GCPhysFault & 3))
|| (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_PASSTHRU
- || (cb == 8 && !(GCPhysFault & 7)) )
+ || (cb == 8 && !(GCPhysFault & 7) && IOMMMIO_DOES_WRITE_MODE_ALLOW_QWORD(pRange->fFlags)) )
rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
GCPhysFault, (void *)pvData, cb); /** @todo fix const!! */
else
@@ -273,6 +302,7 @@ static int iomMMIODoWrite(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault, c
}
else
rc = VINF_SUCCESS;
+
STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
STAM_COUNTER_INC(&pStats->Accesses);
return VBOXSTRICTRC_TODO(rc);
@@ -459,20 +489,31 @@ static int iomMMIODoRead00s(void *pvValue, size_t cbValue)
/**
* Wrapper which does the read and updates range statistics when such are enabled.
*/
-DECLINLINE(int) iomMMIODoRead(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhys, void *pvValue, unsigned cbValue)
+DECLINLINE(int) iomMMIODoRead(PVM pVM, PVMCPU pVCpu, PIOMMMIORANGE pRange, RTGCPHYS GCPhys, void *pvValue, unsigned cbValue)
{
#ifdef VBOX_WITH_STATISTICS
- PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhys, pRange);
- Assert(pStats);
+ int rcSem = IOM_LOCK_SHARED(pVM);
+ if (rcSem == VERR_SEM_BUSY)
+ return VINF_IOM_R3_MMIO_READ;
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange);
+ if (!pStats)
+# ifdef IN_RING3
+ return VERR_NO_MEMORY;
+# else
+ return VINF_IOM_R3_MMIO_READ;
+# endif
STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a);
#endif
VBOXSTRICTRC rc;
if (RT_LIKELY(pRange->CTX_SUFF(pfnReadCallback)))
{
- if ( (cbValue == 4 && !(GCPhys & 3))
+ if ( ( cbValue == 4
+ && !(GCPhys & 3))
|| (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_PASSTHRU
- || (cbValue == 8 && !(GCPhys & 7)) )
+ || ( cbValue == 8
+ && !(GCPhys & 7)
+ && (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_DWORD_QWORD ) )
rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, pvValue, cbValue);
else
rc = iomMMIODoComplicatedRead(pVM, pRange, GCPhys, pvValue, cbValue);
@@ -487,6 +528,7 @@ DECLINLINE(int) iomMMIODoRead(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhys, vo
case VINF_IOM_MMIO_UNUSED_00: rc = iomMMIODoRead00s(pvValue, cbValue); break;
}
}
+
STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a);
STAM_COUNTER_INC(&pStats->Accesses);
return VBOXSTRICTRC_VAL(rc);
@@ -532,12 +574,14 @@ DECLINLINE(void) iomMMIOStatLength(PVM pVM, unsigned cb)
* @returns VBox status code.
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Pointer to CPUMCTXCORE guest registers structure.
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
* @param GCPhysFault The GC physical address corresponding to pvFault.
*/
-static int iomInterpretMOVxXRead(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault)
+static int iomInterpretMOVxXRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu,
+ PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault)
{
Assert(pRange->CTX_SUFF(pfnReadCallback) || !pRange->pfnReadCallbackR3);
@@ -549,7 +593,7 @@ static int iomInterpretMOVxXRead(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE p
AssertMsg(cb > 0 && cb <= sizeof(uint64_t), ("cb=%d\n", cb));
uint64_t u64Data = 0;
- int rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &u64Data, cb);
+ int rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &u64Data, cb);
if (rc == VINF_SUCCESS)
{
/*
@@ -591,12 +635,14 @@ static int iomInterpretMOVxXRead(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE p
* @returns VBox status code.
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Pointer to CPUMCTXCORE guest registers structure.
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
* @param GCPhysFault The GC physical address corresponding to pvFault.
*/
-static int iomInterpretMOVxXWrite(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault)
+static int iomInterpretMOVxXWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu,
+ PIOMMMIORANGE pRange, RTGCPHYS GCPhysFault)
{
Assert(pRange->CTX_SUFF(pfnWriteCallback) || !pRange->pfnWriteCallbackR3);
@@ -609,7 +655,7 @@ static int iomInterpretMOVxXWrite(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE
bool fRc = iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &u64Data, &cb);
AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
- int rc = iomMMIODoWrite(pVM, pRange, GCPhysFault, &u64Data, cb);
+ int rc = iomMMIODoWrite(pVM, pVCpu, pRange, GCPhysFault, &u64Data, cb);
if (rc == VINF_SUCCESS)
iomMMIOStatLength(pVM, cb);
return rc;
@@ -925,12 +971,14 @@ static uint64_t iomDisModeToMask(DISCPUMODE enmCpuMode)
* @returns VBox status code.
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Trap register frame.
* @param GCPhysFault The GC physical address corresponding to pvFault.
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
*/
-static int iomInterpretSTOS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange)
+static int iomInterpretSTOS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault,
+ PDISCPUSTATE pCpu, PIOMMMIORANGE pRange)
{
/*
* We do not support segment prefixes or REPNE..
@@ -946,7 +994,7 @@ static int iomInterpretSTOS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
if (pCpu->fPrefix & DISPREFIX_REP)
{
#ifndef IN_RC
- if ( CPUMIsGuestIn64BitCode(VMMGetCpu(pVM))
+ if ( CPUMIsGuestIn64BitCode(pVCpu)
&& pRegFrame->rcx >= _4G)
return VINF_EM_RAW_EMULATE_INSTR;
#endif
@@ -1021,7 +1069,7 @@ static int iomInterpretSTOS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
/* fill loop. */
do
{
- rc = iomMMIODoWrite(pVM, pRange, Phys, &u64Data, cb);
+ rc = iomMMIODoWrite(pVM, pVCpu, pRange, Phys, &u64Data, cb);
if (rc != VINF_SUCCESS)
break;
@@ -1057,12 +1105,14 @@ static int iomInterpretSTOS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
* @returns VBox status code.
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Trap register frame.
* @param GCPhysFault The GC physical address corresponding to pvFault.
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
*/
-static int iomInterpretLODS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange)
+static int iomInterpretLODS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu,
+ PIOMMMIORANGE pRange)
{
Assert(pRange->CTX_SUFF(pfnReadCallback) || !pRange->pfnReadCallbackR3);
@@ -1082,7 +1132,7 @@ static int iomInterpretLODS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
/*
* Perform read.
*/
- int rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &pRegFrame->rax, cb);
+ int rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &pRegFrame->rax, cb);
if (rc == VINF_SUCCESS)
{
uint64_t const fAddrMask = iomDisModeToMask((DISCPUMODE)pCpu->uAddrMode);
@@ -1114,7 +1164,8 @@ static int iomInterpretLODS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
*/
-static int iomInterpretCMP(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange)
+static int iomInterpretCMP(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu,
+ PIOMMMIORANGE pRange)
{
Assert(pRange->CTX_SUFF(pfnReadCallback) || !pRange->pfnReadCallbackR3);
@@ -1127,10 +1178,10 @@ static int iomInterpretCMP(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault
int rc;
if (iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &uData1, &cb))
/* cmp reg, [MMIO]. */
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData2, cb);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData2, cb);
else if (iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &uData2, &cb))
/* cmp [MMIO], reg|imm. */
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData1, cb);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData1, cb);
else
{
AssertMsgFailed(("Disassember CMP problem..\n"));
@@ -1167,13 +1218,15 @@ static int iomInterpretCMP(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault
* @returns VBox status code.
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Trap register frame.
* @param GCPhysFault The GC physical address corresponding to pvFault.
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
* @param pfnEmulate Instruction emulation function.
*/
-static int iomInterpretOrXorAnd(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange, PFNEMULATEPARAM3 pfnEmulate)
+static int iomInterpretOrXorAnd(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu,
+ PIOMMMIORANGE pRange, PFNEMULATEPARAM3 pfnEmulate)
{
unsigned cb = 0;
uint64_t uData1 = 0;
@@ -1204,7 +1257,7 @@ static int iomInterpretOrXorAnd(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhys
/* and reg, [MMIO]. */
Assert(pRange->CTX_SUFF(pfnReadCallback) || !pRange->pfnReadCallbackR3);
fAndWrite = false;
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData2, cb);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData2, cb);
}
else if (iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &uData2, &cb))
{
@@ -1217,7 +1270,7 @@ static int iomInterpretOrXorAnd(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhys
fAndWrite = true;
if ( (pRange->CTX_SUFF(pfnReadCallback) || !pRange->pfnReadCallbackR3)
&& (pRange->CTX_SUFF(pfnWriteCallback) || !pRange->pfnWriteCallbackR3))
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData1, cb);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData1, cb);
else
rc = VINF_IOM_R3_MMIO_READ_WRITE;
}
@@ -1236,7 +1289,7 @@ static int iomInterpretOrXorAnd(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhys
if (fAndWrite)
/* Store result to MMIO. */
- rc = iomMMIODoWrite(pVM, pRange, GCPhysFault, &uData1, cb);
+ rc = iomMMIODoWrite(pVM, pVCpu, pRange, GCPhysFault, &uData1, cb);
else
{
/* Store result to register. */
@@ -1266,12 +1319,14 @@ static int iomInterpretOrXorAnd(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhys
* @returns VBox status code.
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Trap register frame.
* @param GCPhysFault The GC physical address corresponding to pvFault.
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
*/
-static int iomInterpretTEST(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange)
+static int iomInterpretTEST(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu,
+ PIOMMMIORANGE pRange)
{
Assert(pRange->CTX_SUFF(pfnReadCallback) || !pRange->pfnReadCallbackR3);
@@ -1283,12 +1338,12 @@ static int iomInterpretTEST(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
if (iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &uData1, &cb))
{
/* and test, [MMIO]. */
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData2, cb);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData2, cb);
}
else if (iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &uData2, &cb))
{
/* test [MMIO], reg|imm. */
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData1, cb);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData1, cb);
}
else
{
@@ -1324,12 +1379,14 @@ static int iomInterpretTEST(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
* @returns VBox status code.
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Trap register frame.
* @param GCPhysFault The GC physical address corresponding to pvFault.
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
*/
-static int iomInterpretBT(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange)
+static int iomInterpretBT(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu,
+ PIOMMMIORANGE pRange)
{
Assert(pRange->CTX_SUFF(pfnReadCallback) || !pRange->pfnReadCallbackR3);
@@ -1346,7 +1403,7 @@ static int iomInterpretBT(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault,
unsigned cbData = DISGetParamSize(pCpu, &pCpu->Param1);
/* bt [MMIO], reg|imm. */
- int rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData, cbData);
+ int rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData, cbData);
if (rc == VINF_SUCCESS)
{
/* Find the bit inside the faulting address */
@@ -1367,12 +1424,14 @@ static int iomInterpretBT(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault,
* @returns VBox status code.
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Trap register frame.
* @param GCPhysFault The GC physical address corresponding to pvFault.
* @param pCpu Disassembler CPU state.
* @param pRange Pointer MMIO range.
*/
-static int iomInterpretXCHG(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, PIOMMMIORANGE pRange)
+static int iomInterpretXCHG(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu,
+ PIOMMMIORANGE pRange)
{
/* Check for read & write handlers since IOMMMIOHandler doesn't cover this. */
if ( (!pRange->CTX_SUFF(pfnReadCallback) && pRange->pfnReadCallbackR3)
@@ -1386,11 +1445,11 @@ static int iomInterpretXCHG(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
if (iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &uData1, &cb))
{
/* xchg reg, [MMIO]. */
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData2, cb);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData2, cb);
if (rc == VINF_SUCCESS)
{
/* Store result to MMIO. */
- rc = iomMMIODoWrite(pVM, pRange, GCPhysFault, &uData1, cb);
+ rc = iomMMIODoWrite(pVM, pVCpu, pRange, GCPhysFault, &uData1, cb);
if (rc == VINF_SUCCESS)
{
@@ -1407,11 +1466,11 @@ static int iomInterpretXCHG(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
else if (iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &uData2, &cb))
{
/* xchg [MMIO], reg. */
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, &uData1, cb);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, &uData1, cb);
if (rc == VINF_SUCCESS)
{
/* Store result to MMIO. */
- rc = iomMMIODoWrite(pVM, pRange, GCPhysFault, &uData2, cb);
+ rc = iomMMIODoWrite(pVM, pVCpu, pRange, GCPhysFault, &uData2, cb);
if (rc == VINF_SUCCESS)
{
/* Store result to register. */
@@ -1419,10 +1478,10 @@ static int iomInterpretXCHG(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
AssertMsg(fRc, ("Failed to store register value!\n")); NOREF(fRc);
}
else
- AssertMsg(rc == VINF_IOM_R3_MMIO_READ_WRITE || rc == VINF_IOM_R3_MMIO_WRITE || rc == VINF_PATM_HC_MMIO_PATCH_WRITE, ("rc=%Rrc\n", rc));
+ AssertMsg(rc == VINF_IOM_R3_MMIO_READ_WRITE || rc == VINF_IOM_R3_MMIO_WRITE || rc == VINF_PATM_HC_MMIO_PATCH_WRITE || rc == VINF_EM_RAW_EMULATE_IO_BLOCK, ("rc=%Rrc\n", rc));
}
else
- AssertMsg(rc == VINF_IOM_R3_MMIO_READ_WRITE || rc == VINF_IOM_R3_MMIO_READ || rc == VINF_PATM_HC_MMIO_PATCH_READ, ("rc=%Rrc\n", rc));
+ AssertMsg(rc == VINF_IOM_R3_MMIO_READ_WRITE || rc == VINF_IOM_R3_MMIO_READ || rc == VINF_PATM_HC_MMIO_PATCH_READ || rc == VINF_EM_RAW_EMULATE_IO_BLOCK, ("rc=%Rrc\n", rc));
}
else
{
@@ -1438,16 +1497,16 @@ static int iomInterpretXCHG(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFaul
*
* @returns VBox status code (appropriate for GC return).
* @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param uErrorCode CPU Error code. This is UINT32_MAX when we don't have
* any error code (the EPT misconfig hack).
* @param pCtxCore Trap register frame.
* @param GCPhysFault The GC physical address corresponding to pvFault.
* @param pvUser Pointer to the MMIO ring-3 range entry.
*/
-static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault, void *pvUser)
+static int iomMMIOHandler(PVM pVM, PVMCPU pVCpu, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault, void *pvUser)
{
- /* Take the IOM lock before performing any MMIO. */
- int rc = IOM_LOCK(pVM);
+ int rc = IOM_LOCK_SHARED(pVM);
#ifndef IN_RING3
if (rc == VERR_SEM_BUSY)
return VINF_IOM_R3_MMIO_READ_WRITE;
@@ -1455,27 +1514,28 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
AssertRC(rc);
STAM_PROFILE_START(&pVM->iom.s.StatRZMMIOHandler, a);
- Log(("iomMMIOHandler: GCPhys=%RGp uErr=%#x rip=%RGv\n",
- GCPhysFault, uErrorCode, (RTGCPTR)pCtxCore->rip));
+ Log(("iomMMIOHandler: GCPhys=%RGp uErr=%#x rip=%RGv\n", GCPhysFault, uErrorCode, (RTGCPTR)pCtxCore->rip));
PIOMMMIORANGE pRange = (PIOMMMIORANGE)pvUser;
Assert(pRange);
- Assert(pRange == iomMmioGetRange(pVM, GCPhysFault));
+ Assert(pRange == iomMmioGetRange(pVM, pVCpu, GCPhysFault));
+ iomMmioRetainRange(pRange);
+#ifndef VBOX_WITH_STATISTICS
+ IOM_UNLOCK_SHARED(pVM);
-#ifdef VBOX_WITH_STATISTICS
+#else
/*
- * Locate the statistics, if > PAGE_SIZE we'll use the first byte for everything.
+ * Locate the statistics.
*/
- PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhysFault, pRange);
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhysFault, pRange);
if (!pStats)
{
+ iomMmioReleaseRange(pVM, pRange);
# ifdef IN_RING3
- IOM_UNLOCK(pVM);
return VERR_NO_MEMORY;
# else
STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
STAM_COUNTER_INC(&pVM->iom.s.StatRZMMIOFailures);
- IOM_UNLOCK(pVM);
return VINF_IOM_R3_MMIO_READ_WRITE;
# endif
}
@@ -1504,7 +1564,7 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
STAM_COUNTER_INC(&pVM->iom.s.StatRZMMIOFailures);
- IOM_UNLOCK(pVM);
+ iomMmioReleaseRange(pVM, pRange);
return VINF_IOM_R3_MMIO_READ_WRITE;
}
#endif /* !IN_RING3 */
@@ -1512,9 +1572,7 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
/*
* Retain the range and do locking.
*/
- iomMmioRetainRange(pRange);
PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
- IOM_UNLOCK(pVM);
rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ_WRITE);
if (rc != VINF_SUCCESS)
{
@@ -1525,14 +1583,13 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
/*
* Disassemble the instruction and interpret it.
*/
- PVMCPU pVCpu = VMMGetCpu(pVM);
PDISCPUSTATE pDis = &pVCpu->iom.s.DisState;
unsigned cbOp;
rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
if (RT_FAILURE(rc))
{
- iomMmioReleaseRange(pVM, pRange);
PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
+ iomMmioReleaseRange(pVM, pRange);
return rc;
}
switch (pDis->pCurInstr->uOpcode)
@@ -1546,9 +1603,9 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
if (uErrorCode != UINT32_MAX /* EPT+MMIO optimization */
? uErrorCode & X86_TRAP_PF_RW
: DISUSE_IS_EFFECTIVE_ADDR(pDis->Param1.fUse))
- rc = iomInterpretMOVxXWrite(pVM, pCtxCore, pDis, pRange, GCPhysFault);
+ rc = iomInterpretMOVxXWrite(pVM, pVCpu, pCtxCore, pDis, pRange, GCPhysFault);
else
- rc = iomInterpretMOVxXRead(pVM, pCtxCore, pDis, pRange, GCPhysFault);
+ rc = iomInterpretMOVxXRead(pVM, pVCpu, pCtxCore, pDis, pRange, GCPhysFault);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstMov, b);
break;
}
@@ -1575,7 +1632,7 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
case OP_STOSWD:
Assert(uErrorCode & X86_TRAP_PF_RW);
STAM_PROFILE_START(&pVM->iom.s.StatRZInstStos, d);
- rc = iomInterpretSTOS(pVM, pCtxCore, GCPhysFault, pDis, pRange);
+ rc = iomInterpretSTOS(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstStos, d);
break;
@@ -1583,52 +1640,52 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
case OP_LODSWD:
Assert(!(uErrorCode & X86_TRAP_PF_RW) || uErrorCode == UINT32_MAX);
STAM_PROFILE_START(&pVM->iom.s.StatRZInstLods, e);
- rc = iomInterpretLODS(pVM, pCtxCore, GCPhysFault, pDis, pRange);
+ rc = iomInterpretLODS(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstLods, e);
break;
case OP_CMP:
Assert(!(uErrorCode & X86_TRAP_PF_RW) || uErrorCode == UINT32_MAX);
STAM_PROFILE_START(&pVM->iom.s.StatRZInstCmp, f);
- rc = iomInterpretCMP(pVM, pCtxCore, GCPhysFault, pDis, pRange);
+ rc = iomInterpretCMP(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstCmp, f);
break;
case OP_AND:
STAM_PROFILE_START(&pVM->iom.s.StatRZInstAnd, g);
- rc = iomInterpretOrXorAnd(pVM, pCtxCore, GCPhysFault, pDis, pRange, EMEmulateAnd);
+ rc = iomInterpretOrXorAnd(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange, EMEmulateAnd);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstAnd, g);
break;
case OP_OR:
STAM_PROFILE_START(&pVM->iom.s.StatRZInstOr, k);
- rc = iomInterpretOrXorAnd(pVM, pCtxCore, GCPhysFault, pDis, pRange, EMEmulateOr);
+ rc = iomInterpretOrXorAnd(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange, EMEmulateOr);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstOr, k);
break;
case OP_XOR:
STAM_PROFILE_START(&pVM->iom.s.StatRZInstXor, m);
- rc = iomInterpretOrXorAnd(pVM, pCtxCore, GCPhysFault, pDis, pRange, EMEmulateXor);
+ rc = iomInterpretOrXorAnd(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange, EMEmulateXor);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstXor, m);
break;
case OP_TEST:
Assert(!(uErrorCode & X86_TRAP_PF_RW) || uErrorCode == UINT32_MAX);
STAM_PROFILE_START(&pVM->iom.s.StatRZInstTest, h);
- rc = iomInterpretTEST(pVM, pCtxCore, GCPhysFault, pDis, pRange);
+ rc = iomInterpretTEST(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstTest, h);
break;
case OP_BT:
Assert(!(uErrorCode & X86_TRAP_PF_RW) || uErrorCode == UINT32_MAX);
STAM_PROFILE_START(&pVM->iom.s.StatRZInstBt, l);
- rc = iomInterpretBT(pVM, pCtxCore, GCPhysFault, pDis, pRange);
+ rc = iomInterpretBT(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstBt, l);
break;
case OP_XCHG:
STAM_PROFILE_START(&pVM->iom.s.StatRZInstXchg, i);
- rc = iomInterpretXCHG(pVM, pCtxCore, GCPhysFault, pDis, pRange);
+ rc = iomInterpretXCHG(pVM, pVCpu, pCtxCore, GCPhysFault, pDis, pRange);
STAM_PROFILE_STOP(&pVM->iom.s.StatRZInstXchg, i);
break;
@@ -1665,8 +1722,8 @@ static int iomMMIOHandler(PVM pVM, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, R
}
STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
- iomMmioReleaseRange(pVM, pRange);
PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
+ iomMmioReleaseRange(pVM, pRange);
return rc;
}
@@ -1685,7 +1742,7 @@ VMMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore,
{
LogFlow(("IOMMMIOHandler: GCPhys=%RGp uErr=%#x pvFault=%RGv rip=%RGv\n",
GCPhysFault, (uint32_t)uErrorCode, pvFault, (RTGCPTR)pCtxCore->rip));
- VBOXSTRICTRC rcStrict = iomMMIOHandler(pVM, (uint32_t)uErrorCode, pCtxCore, GCPhysFault, pvUser);
+ VBOXSTRICTRC rcStrict = iomMMIOHandler(pVM, VMMGetCpu(pVM), (uint32_t)uErrorCode, pCtxCore, GCPhysFault, pvUser);
return VBOXSTRICTRC_VAL(rcStrict);
}
@@ -1694,19 +1751,33 @@ VMMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore,
*
* @returns VBox status code (appropriate for GC return).
* @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param uErrorCode CPU Error code.
* @param pCtxCore Trap register frame.
* @param GCPhysFault The GC physical address.
*/
-VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault)
+VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault)
{
- int rc2 = IOM_LOCK(pVM); NOREF(rc2);
+ /*
+ * We don't have a range here, so look it up before calling the common function.
+ */
+ int rc2 = IOM_LOCK_SHARED(pVM); NOREF(rc2);
#ifndef IN_RING3
if (rc2 == VERR_SEM_BUSY)
return VINF_IOM_R3_MMIO_READ_WRITE;
#endif
- VBOXSTRICTRC rcStrict = iomMMIOHandler(pVM, (uint32_t)uErrorCode, pCtxCore, GCPhysFault, iomMmioGetRange(pVM, GCPhysFault));
- IOM_UNLOCK(pVM);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhysFault);
+ if (RT_UNLIKELY(!pRange))
+ {
+ IOM_UNLOCK_SHARED(pVM);
+ return VERR_IOM_MMIO_RANGE_NOT_FOUND;
+ }
+ iomMmioRetainRange(pRange);
+ IOM_UNLOCK_SHARED(pVM);
+
+ VBOXSTRICTRC rcStrict = iomMMIOHandler(pVM, pVCpu, (uint32_t)uErrorCode, pCtxCore, GCPhysFault, pRange);
+
+ iomMmioReleaseRange(pVM, pRange);
return VBOXSTRICTRC_VAL(rcStrict);
}
@@ -1728,26 +1799,27 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXC
DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhysFault, void *pvPhys, void *pvBuf, size_t cbBuf,
PGMACCESSTYPE enmAccessType, void *pvUser)
{
+ PVMCPU pVCpu = VMMGetCpu(pVM);
PIOMMMIORANGE pRange = (PIOMMMIORANGE)pvUser;
STAM_COUNTER_INC(&pVM->iom.s.StatR3MMIOHandler);
- AssertMsg(cbBuf == 1 || cbBuf == 2 || cbBuf == 4 || cbBuf == 8, ("%zu\n", cbBuf));
+ AssertMsg(cbBuf >= 1 && cbBuf <= 16, ("%zu\n", cbBuf));
AssertPtr(pRange);
NOREF(pvPhys);
/*
* Validate the range.
*/
- int rc = IOM_LOCK(pVM);
+ int rc = IOM_LOCK_SHARED(pVM);
AssertRC(rc);
- Assert(pRange == iomMmioGetRange(pVM, GCPhysFault));
+ Assert(pRange == iomMmioGetRange(pVM, pVCpu, GCPhysFault));
/*
* Perform locking.
*/
iomMmioRetainRange(pRange);
PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
- IOM_UNLOCK(pVM);
+ IOM_UNLOCK_SHARED(pVM);
rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ_WRITE);
if (rc != VINF_SUCCESS)
{
@@ -1759,9 +1831,9 @@ DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhysFault, void *pvPhys,
* Perform the access.
*/
if (enmAccessType == PGMACCESSTYPE_READ)
- rc = iomMMIODoRead(pVM, pRange, GCPhysFault, pvBuf, (unsigned)cbBuf);
+ rc = iomMMIODoRead(pVM, pVCpu, pRange, GCPhysFault, pvBuf, (unsigned)cbBuf);
else
- rc = iomMMIODoWrite(pVM, pRange, GCPhysFault, pvBuf, (unsigned)cbBuf);
+ rc = iomMMIODoWrite(pVM, pVCpu, pRange, GCPhysFault, pvBuf, (unsigned)cbBuf);
AssertRC(rc);
iomMmioReleaseRange(pVM, pRange);
@@ -1777,14 +1849,15 @@ DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhysFault, void *pvPhys,
* @returns VBox status code.
*
* @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param GCPhys The physical address to read.
* @param pu32Value Where to store the value read.
* @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes.
*/
-VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue)
+VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue)
{
/* Take the IOM lock before performing any MMIO. */
- VBOXSTRICTRC rc = IOM_LOCK(pVM);
+ VBOXSTRICTRC rc = IOM_LOCK_SHARED(pVM);
#ifndef IN_RING3
if (rc == VERR_SEM_BUSY)
return VINF_IOM_R3_MMIO_WRITE;
@@ -1797,18 +1870,22 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
/*
* Lookup the current context range node and statistics.
*/
- PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhys);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhys);
if (!pRange)
{
AssertMsgFailed(("Handlers and page tables are out of sync or something! GCPhys=%RGp cbValue=%d\n", GCPhys, cbValue));
- IOM_UNLOCK(pVM);
+ IOM_UNLOCK_SHARED(pVM);
return VERR_IOM_MMIO_RANGE_NOT_FOUND;
}
-#ifdef VBOX_WITH_STATISTICS
- PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhys, pRange);
+ iomMmioRetainRange(pRange);
+#ifndef VBOX_WITH_STATISTICS
+ IOM_UNLOCK_SHARED(pVM);
+
+#else /* VBOX_WITH_STATISTICS */
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange);
if (!pStats)
{
- IOM_UNLOCK(pVM);
+ iomMmioReleaseRange(pVM, pRange);
# ifdef IN_RING3
return VERR_NO_MEMORY;
# else
@@ -1823,9 +1900,7 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
/*
* Perform locking.
*/
- iomMmioRetainRange(pRange);
PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
- IOM_UNLOCK(pVM);
rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_WRITE);
if (rc != VINF_SUCCESS)
{
@@ -1849,8 +1924,8 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
{
case VINF_SUCCESS:
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue));
- iomMmioReleaseRange(pVM, pRange);
PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
+ iomMmioReleaseRange(pVM, pRange);
return rc;
#ifndef IN_RING3
case VINF_IOM_R3_MMIO_READ:
@@ -1859,22 +1934,22 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
#endif
default:
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
- iomMmioReleaseRange(pVM, pRange);
PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
+ iomMmioReleaseRange(pVM, pRange);
return rc;
case VINF_IOM_MMIO_UNUSED_00:
iomMMIODoRead00s(pu32Value, cbValue);
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
- iomMmioReleaseRange(pVM, pRange);
PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
+ iomMmioReleaseRange(pVM, pRange);
return VINF_SUCCESS;
case VINF_IOM_MMIO_UNUSED_FF:
iomMMIODoReadFFs(pu32Value, cbValue);
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
- iomMmioReleaseRange(pVM, pRange);
PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
+ iomMmioReleaseRange(pVM, pRange);
return VINF_SUCCESS;
}
/* not reached */
@@ -1883,7 +1958,7 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
if (pRange->pfnReadCallbackR3)
{
STAM_COUNTER_INC(&pStats->CTX_MID_Z(Read,ToR3));
- IOM_UNLOCK(pVM);
+ iomMmioReleaseRange(pVM, pRange);
return VINF_IOM_R3_MMIO_READ;
}
#endif
@@ -1895,7 +1970,7 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a);
iomMMIODoReadFFs(pu32Value, cbValue);
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue));
- IOM_UNLOCK(pVM);
+ iomMmioReleaseRange(pVM, pRange);
return VINF_SUCCESS;
}
@@ -1906,14 +1981,15 @@ VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value,
* @returns VBox status code.
*
* @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param GCPhys The physical address to write to.
* @param u32Value The value to write.
* @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes.
*/
-VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue)
+VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue)
{
/* Take the IOM lock before performing any MMIO. */
- VBOXSTRICTRC rc = IOM_LOCK(pVM);
+ VBOXSTRICTRC rc = IOM_LOCK_SHARED(pVM);
#ifndef IN_RING3
if (rc == VERR_SEM_BUSY)
return VINF_IOM_R3_MMIO_WRITE;
@@ -1926,18 +2002,22 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value,
/*
* Lookup the current context range node.
*/
- PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhys);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhys);
if (!pRange)
{
AssertMsgFailed(("Handlers and page tables are out of sync or something! GCPhys=%RGp cbValue=%d\n", GCPhys, cbValue));
- IOM_UNLOCK(pVM);
+ IOM_UNLOCK_SHARED(pVM);
return VERR_IOM_MMIO_RANGE_NOT_FOUND;
}
-#ifdef VBOX_WITH_STATISTICS
- PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhys, pRange);
+ iomMmioRetainRange(pRange);
+#ifndef VBOX_WITH_STATISTICS
+ IOM_UNLOCK_SHARED(pVM);
+
+#else /* VBOX_WITH_STATISTICS */
+ PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange);
if (!pStats)
{
- IOM_UNLOCK(pVM);
+ iomMmioReleaseRange(pVM, pRange);
# ifdef IN_RING3
return VERR_NO_MEMORY;
# else
@@ -1952,9 +2032,7 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value,
/*
* Perform locking.
*/
- iomMmioRetainRange(pRange);
PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
- IOM_UNLOCK(pVM);
rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ);
if (rc != VINF_SUCCESS)
{
@@ -1988,7 +2066,7 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value,
if (pRange->pfnWriteCallbackR3)
{
STAM_COUNTER_INC(&pStats->CTX_MID_Z(Write,ToR3));
- IOM_UNLOCK(pVM);
+ iomMmioReleaseRange(pVM, pRange);
return VINF_IOM_R3_MMIO_WRITE;
}
#endif
@@ -1999,7 +2077,7 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value,
STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, VINF_SUCCESS));
- IOM_UNLOCK(pVM);
+ iomMmioReleaseRange(pVM, pRange);
return VINF_SUCCESS;
}
@@ -2022,13 +2100,14 @@ VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value,
* @retval VINF_EM_RESCHEDULE_REM The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Pointer to CPUMCTXCORE guest registers structure.
* @param uPort IO Port
* @param uPrefix IO instruction prefix
* @param enmAddrMode The address mode.
* @param cbTransfer Size of transfer unit
*/
-VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix,
+VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix,
DISCPUMODE enmAddrMode, uint32_t cbTransfer)
{
STAM_COUNTER_INC(&pVM->iom.s.StatInstIns);
@@ -2041,8 +2120,6 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_
|| pRegFrame->eflags.Bits.u1DF)
return VINF_EM_RAW_EMULATE_INSTR;
- PVMCPU pVCpu = VMMGetCpu(pVM);
-
/*
* Get bytes/words/dwords count to transfer.
*/
@@ -2088,7 +2165,7 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_
/* If the device supports string transfers, ask it to do as
* much as it wants. The rest is done with single-word transfers. */
const RTGCUINTREG cTransfersOrg = cTransfers;
- rcStrict = IOMIOPortReadString(pVM, uPort, &GCPtrDst, &cTransfers, cbTransfer);
+ rcStrict = IOMIOPortReadString(pVM, pVCpu, uPort, &GCPtrDst, &cTransfers, cbTransfer);
AssertRC(VBOXSTRICTRC_VAL(rcStrict)); Assert(cTransfers <= cTransfersOrg);
pRegFrame->rdi = ((pRegFrame->rdi + (cTransfersOrg - cTransfers) * cbTransfer) & fAddrMask)
| (pRegFrame->rdi & ~fAddrMask);
@@ -2100,7 +2177,7 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_
while (cTransfers && rcStrict == VINF_SUCCESS)
{
uint32_t u32Value;
- rcStrict = IOMIOPortRead(pVM, uPort, &u32Value, cbTransfer);
+ rcStrict = IOMIOPortRead(pVM, pVCpu, uPort, &u32Value, cbTransfer);
if (!IOM_SUCCESS(rcStrict))
break;
rc2 = iomRamWrite(pVCpu, pRegFrame, GCPtrDst, &u32Value, cbTransfer);
@@ -2124,6 +2201,7 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_
}
+#if !defined(VBOX_WITH_FIRST_IEM_STEP) || defined(IN_RC) /* Latter for IOMRCIOPortHandler */
/**
* [REP*] INSB/INSW/INSD
* ES:EDI,DX[,ECX]
@@ -2140,10 +2218,11 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_
* @retval VINF_EM_RESCHEDULE_REM The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Pointer to CPUMCTXCORE guest registers structure.
* @param pCpu Disassembler CPU state.
*/
-VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
+VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
{
/*
* Get port number directly from the register (no need to bother the
@@ -2163,8 +2242,9 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUST
return rcStrict;
}
- return IOMInterpretINSEx(pVM, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb);
+ return IOMInterpretINSEx(pVM, pVCpu, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb);
}
+#endif /* !IEM || RC */
/**
@@ -2184,13 +2264,14 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUST
* @retval VINF_EM_RESCHEDULE_REM The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Pointer to CPUMCTXCORE guest registers structure.
* @param uPort IO Port
* @param uPrefix IO instruction prefix
* @param enmAddrMode The address mode.
* @param cbTransfer Size of transfer unit
*/
-VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix,
+VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix,
DISCPUMODE enmAddrMode, uint32_t cbTransfer)
{
STAM_COUNTER_INC(&pVM->iom.s.StatInstOuts);
@@ -2203,8 +2284,6 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32
|| pRegFrame->eflags.Bits.u1DF)
return VINF_EM_RAW_EMULATE_INSTR;
- PVMCPU pVCpu = VMMGetCpu(pVM);
-
/*
* Get bytes/words/dwords count to transfer.
*/
@@ -2252,7 +2331,7 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32
* much as it wants. The rest is done with single-word transfers.
*/
const RTGCUINTREG cTransfersOrg = cTransfers;
- rcStrict = IOMIOPortWriteString(pVM, uPort, &GCPtrSrc, &cTransfers, cbTransfer);
+ rcStrict = IOMIOPortWriteString(pVM, pVCpu, uPort, &GCPtrSrc, &cTransfers, cbTransfer);
AssertRC(VBOXSTRICTRC_VAL(rcStrict)); Assert(cTransfers <= cTransfersOrg);
pRegFrame->rsi = ((pRegFrame->rsi + (cTransfersOrg - cTransfers) * cbTransfer) & fAddrMask)
| (pRegFrame->rsi & ~fAddrMask);
@@ -2268,7 +2347,7 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32
rcStrict = iomRamRead(pVCpu, &u32Value, GCPtrSrc, cbTransfer);
if (rcStrict != VINF_SUCCESS)
break;
- rcStrict = IOMIOPortWrite(pVM, uPort, u32Value, cbTransfer);
+ rcStrict = IOMIOPortWrite(pVM, pVCpu, uPort, u32Value, cbTransfer);
if (!IOM_SUCCESS(rcStrict))
break;
GCPtrSrc = (RTGCPTR)((RTUINTPTR)GCPtrSrc + cbTransfer);
@@ -2291,6 +2370,7 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32
}
+#if !defined(VBOX_WITH_FIRST_IEM_STEP) || defined(IN_RC) /* Latter for IOMRCIOPortHandler */
/**
* [REP*] OUTSB/OUTSW/OUTSD
* DS:ESI,DX[,ECX]
@@ -2307,10 +2387,11 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32
* @retval VINF_EM_RESCHEDULE_REM The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
*
* @param pVM The virtual machine.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param pRegFrame Pointer to CPUMCTXCORE guest registers structure.
* @param pCpu Disassembler CPU state.
*/
-VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
+VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
{
/*
* Get port number from the first parameter.
@@ -2332,8 +2413,9 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUS
return rcStrict;
}
- return IOMInterpretOUTSEx(pVM, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb);
+ return IOMInterpretOUTSEx(pVM, pVCpu, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb);
}
+#endif /* !IEM || RC */
#ifndef IN_RC
@@ -2353,25 +2435,26 @@ VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUS
*/
VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags)
{
+# ifndef IEM_VERIFICATION_MODE_FULL
/* Currently only called from the VGA device during MMIO. */
Log(("IOMMMIOMapMMIO2Page %RGp -> %RGp flags=%RX64\n", GCPhys, GCPhysRemapped, fPageFlags));
AssertReturn(fPageFlags == (X86_PTE_RW | X86_PTE_P), VERR_INVALID_PARAMETER);
PVMCPU pVCpu = VMMGetCpu(pVM);
/* This currently only works in real mode, protected mode without paging or with nested paging. */
- if ( !HWACCMIsEnabled(pVM) /* useless without VT-x/AMD-V */
+ if ( !HMIsEnabled(pVM) /* useless without VT-x/AMD-V */
|| ( CPUMIsGuestInPagedProtectedMode(pVCpu)
- && !HWACCMIsNestedPagingActive(pVM)))
+ && !HMIsNestedPagingActive(pVM)))
return VINF_SUCCESS; /* ignore */
- int rc = IOM_LOCK(pVM);
+ int rc = IOM_LOCK_SHARED(pVM);
if (RT_FAILURE(rc))
return VINF_SUCCESS; /* better luck the next time around */
/*
* Lookup the context range node the page belongs to.
*/
- PIOMMMIORANGE pRange = iomMmioGetRange(pVM, GCPhys);
+ PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhys);
AssertMsgReturn(pRange,
("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
@@ -2386,7 +2469,7 @@ VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapp
rc = PGMHandlerPhysicalPageAlias(pVM, pRange->GCPhys, GCPhys, GCPhysRemapped);
- IOM_UNLOCK(pVM);
+ IOM_UNLOCK_SHARED(pVM);
AssertRCReturn(rc, rc);
/*
@@ -2395,20 +2478,22 @@ VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapp
*
* Note: This is a NOP in the EPT case; we'll just let it fault again to resync the page.
*/
-#if 0 /* The assertion is wrong for the PGM_SYNC_CLEAR_PGM_POOL and VINF_PGM_HANDLER_ALREADY_ALIASED cases. */
-# ifdef VBOX_STRICT
+# if 0 /* The assertion is wrong for the PGM_SYNC_CLEAR_PGM_POOL and VINF_PGM_HANDLER_ALREADY_ALIASED cases. */
+# ifdef VBOX_STRICT
uint64_t fFlags;
RTHCPHYS HCPhys;
rc = PGMShwGetPage(pVCpu, (RTGCPTR)GCPhys, &fFlags, &HCPhys);
Assert(rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT);
-# endif
-#endif
+# endif
+# endif
rc = PGMPrefetchPage(pVCpu, (RTGCPTR)GCPhys);
Assert(rc == VINF_SUCCESS || rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT);
+# endif /* !IEM_VERIFICATION_MODE_FULL */
return VINF_SUCCESS;
}
+# ifndef IEM_VERIFICATION_MODE_FULL
/**
* Mapping a HC page in place of an MMIO page for direct access.
*
@@ -2416,28 +2501,27 @@ VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapp
*
* @returns VBox status code.
*
- * @param pVM The virtual machine.
+ * @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the VMCPU.
* @param GCPhys The address of the MMIO page to be changed.
* @param HCPhys The address of the host physical page.
* @param fPageFlags Page flags to set. Must be (X86_PTE_RW | X86_PTE_P)
* for the time being.
*/
-VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags)
+VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags)
{
/* Currently only called from VT-x code during a page fault. */
Log(("IOMMMIOMapMMIOHCPage %RGp -> %RGp flags=%RX64\n", GCPhys, HCPhys, fPageFlags));
AssertReturn(fPageFlags == (X86_PTE_RW | X86_PTE_P), VERR_INVALID_PARAMETER);
- Assert(HWACCMIsEnabled(pVM));
-
- PVMCPU pVCpu = VMMGetCpu(pVM);
+ Assert(HMIsEnabled(pVM));
/*
* Lookup the context range node the page belongs to.
*/
#ifdef VBOX_STRICT
/* Can't lock IOM here due to potential deadlocks in the VGA device; not safe to access. */
- PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(pVM, GCPhys);
+ PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(pVM, pVCpu, GCPhys);
AssertMsgReturn(pRange,
("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
Assert((pRange->GCPhys & PAGE_OFFSET_MASK) == 0);
@@ -2463,6 +2547,7 @@ VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uin
Assert(rc == VINF_SUCCESS || rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT);
return VINF_SUCCESS;
}
+#endif /* !IEM_VERIFICATION_MODE_FULL */
/**
@@ -2480,9 +2565,9 @@ VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys)
PVMCPU pVCpu = VMMGetCpu(pVM);
/* This currently only works in real mode, protected mode without paging or with nested paging. */
- if ( !HWACCMIsEnabled(pVM) /* useless without VT-x/AMD-V */
+ if ( !HMIsEnabled(pVM) /* useless without VT-x/AMD-V */
|| ( CPUMIsGuestInPagedProtectedMode(pVCpu)
- && !HWACCMIsNestedPagingActive(pVM)))
+ && !HMIsNestedPagingActive(pVM)))
return VINF_SUCCESS; /* ignore */
/*
@@ -2490,7 +2575,7 @@ VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys)
*/
#ifdef VBOX_STRICT
/* Can't lock IOM here due to potential deadlocks in the VGA device; not safe to access. */
- PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(pVM, GCPhys);
+ PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(pVM, pVCpu, GCPhys);
AssertMsgReturn(pRange,
("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
Assert((pRange->GCPhys & PAGE_OFFSET_MASK) == 0);
@@ -2507,7 +2592,7 @@ VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys)
AssertRC(rc);
#ifdef VBOX_STRICT
- if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
+ if (!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
{
uint32_t cb = pRange->cb;
GCPhys = pRange->GCPhys;