diff options
Diffstat (limited to 'src/VBox/VMM/VMMAll/IOMAllMMIO.cpp')
| -rw-r--r-- | src/VBox/VMM/VMMAll/IOMAllMMIO.cpp | 373 |
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; |
