PGMAllPhys.cpp revision be3d2ee73e057662b3a4313840d0b92ac66ebd5e
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * PGM - Page Manager and Monitor, Physical Memory Addressing.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * available from http://www.virtualbox.org. This file is free software;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * General Public License as published by the Free Software Foundation,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * If you received this file as part of a commercial VirtualBox
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * distribution, then only the terms of your commercial VirtualBox
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * license agreement apply instead of the previous paragraph.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** @def PGM_IGNORE_RAM_FLAGS_RESERVED
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Don't respect the MM_RAM_FLAGS_RESERVED flag when converting to HC addresses.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Since this flag is currently incorrectly kept set for ROM regions we will
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * have to ignore it for now so we don't break stuff.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/*******************************************************************************
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync* Header Files *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync*******************************************************************************/
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Checks if Address Gate 20 is enabled or not.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @returns true if enabled.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @returns false if disabled.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @param pVM VM handle.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync LogFlow(("PGMPhysIsA20Enabled %d\n", pVM->pgm.s.fA20Enabled));
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync return !!pVM->pgm.s.fA20Enabled ; /* stupid MS compiler doesn't trust me. */
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * Validates a GC physical address.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns true if valid.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns false if invalid.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param GCPhys The physical address to validate.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncPGMDECL(bool) PGMPhysIsGCPhysValid(PVM pVM, RTGCPHYS GCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return true;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return false;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Checks if a GC physical address is a normal page,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * i.e. not ROM, MMIO or reserved.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns true if normal.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns false if invalid, ROM, MMIO or reserved page.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param GCPhys The physical address to check.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncPGMDECL(bool) PGMPhysIsGCPhysNormal(PVM pVM, RTGCPHYS GCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return !(pRam->aHCPhys[off >> PAGE_SHIFT] & (MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO2));
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return false;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Converts a GC physical address to a HC physical address.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VINF_SUCCESS on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * page but has no physical backing.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * GC physical address.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param GCPhys The GC physical address to convert.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pHCPhys Where to store the HC physical address on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncPGMDECL(int) PGMPhysGCPhys2HCPhys(PVM pVM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (RT_UNLIKELY(!(pRam->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK)))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync int rc = CTXALLMID(VMM, CallHost)(pVM, VMMCALLHOST_PGM_RAM_GROW_RANGE, GCPhys);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTHCPHYS HCPhys = pRam->aHCPhys[off >> PAGE_SHIFT];
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * Converts a GC physical address to a HC pointer.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @returns VINF_SUCCESS on success.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @returns VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * page but has no physical backing.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * GC physical address.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @param pVM The VM handle.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @param GCPhys The GC physical address to convert.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @param pHCPtr Where to store the HC pointer on success.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsyncPGMDECL(int) PGMPhysGCPhys2HCPtr(PVM pVM, RTGCPHYS GCPhys, PRTHCPTR pHCPtr)
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (RT_UNLIKELY(!(pRam->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK)))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync int rc = CTXALLMID(VMM, CallHost)(pVM, VMMCALLHOST_PGM_RAM_GROW_RANGE, GCPhys);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pHCPtr = (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pvHCChunk)[idx] + (off & PGM_DYNAMIC_CHUNK_OFFSET_MASK));
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (!(pRam->aHCPhys[off >> PAGE_SHIFT] & MM_RAM_FLAGS_RESERVED))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pHCPtr = (RTHCPTR)((RTHCUINTPTR)pRam->pvHC + off);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Validates a HC pointer.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @returns true if valid.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns false if invalid.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @param pVM The VM handle.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @param HCPtr The pointer to validate.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsyncPGMDECL(bool) PGMPhysIsHCPtrValid(PVM pVM, RTHCPTR HCPtr)
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** @note this is quite slow */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (unsigned iChunk = 0; iChunk < (pRam->cb >> PGM_DYNAMIC_CHUNK_SHIFT); iChunk++)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTHCUINTPTR off = (RTHCUINTPTR)HCPtr - (RTHCUINTPTR)CTXSUFF(pRam->pvHCChunk)[iChunk];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return true;
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync RTHCUINTPTR off = (RTHCUINTPTR)HCPtr - (RTHCUINTPTR)pRam->pvHC;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return true;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return false;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Converts a HC pointer to a GC physical address.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VINF_SUCCESS on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VERR_INVALID_POINTER if the pointer is not within the
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * GC physical memory.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param HCPtr The HC pointer to convert.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pGCPhys Where to store the GC physical address on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncPGMDECL(int) PGMPhysHCPtr2GCPhys(PVM pVM, RTHCPTR HCPtr, PRTGCPHYS pGCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges);
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync /** @note this is quite slow */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (unsigned iChunk = 0; iChunk < (pRam->cb >> PGM_DYNAMIC_CHUNK_SHIFT); iChunk++)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTHCUINTPTR off = (RTHCUINTPTR)HCPtr - (RTHCUINTPTR)CTXSUFF(pRam->pvHCChunk)[iChunk];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pGCPhys = pRam->GCPhys + iChunk*PGM_DYNAMIC_CHUNK_SIZE + off;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTHCUINTPTR off = (RTHCUINTPTR)HCPtr - (RTHCUINTPTR)pRam->pvHC;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Converts a HC pointer to a GC physical address.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VINF_SUCCESS on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * page but has no physical backing.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VERR_INVALID_POINTER if the pointer is not within the
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * GC physical memory.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param HCPtr The HC pointer to convert.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pHCPhys Where to store the HC physical address on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncPGMDECL(int) PGMPhysHCPtr2HCPhys(PVM pVM, RTHCPTR HCPtr, PRTHCPHYS pHCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** @note this is quite slow */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (unsigned iChunk = 0; iChunk < (pRam->cb >> PGM_DYNAMIC_CHUNK_SHIFT); iChunk++)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTHCUINTPTR off = (RTHCUINTPTR)HCPtr - (RTHCUINTPTR)CTXSUFF(pRam->pvHCChunk)[iChunk];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTHCPHYS HCPhys = pRam->aHCPhys[off >> PAGE_SHIFT];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTHCUINTPTR off = (RTHCUINTPTR)HCPtr - (RTHCUINTPTR)pRam->pvHC;
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync RTHCPHYS HCPhys = pRam->aHCPhys[off >> PAGE_SHIFT];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Validates a HC Physical address.
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync * This is an extremely slow API, don't use it!
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns true if valid.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns false if invalid.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
a898eb6a3ace2594099a60b478ae5cc164bfe3dcvboxsync * @param HCPhys The physical address to validate.
a898eb6a3ace2594099a60b478ae5cc164bfe3dcvboxsyncPGMDECL(bool) PGMPhysIsHCPhysValid(PVM pVM, RTHCPHYS HCPhys)
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync int rc = PGMPhysHCPhys2GCPhys(pVM, HCPhys, &GCPhys);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Converts a HC physical address to a GC physical address.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * This is an extremely slow API, don't use it!
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VINF_SUCCESS on success.
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync * @returns VERR_INVALID_POINTER if the HC physical address is
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync * not within the GC physical memory.
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync * @param pVM The VM handle.
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync * @param HCPhys The HC physical address to convert.
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync * @param pGCPhys Where to store the GC physical address on success.
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsyncPGMDECL(int) PGMPhysHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys)
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges);
while (iPage-- > 0)
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VINF_SUCCESS;
return VERR_INVALID_POINTER;
pRam;
while (iPage-- > 0)
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
*pHCPtr = (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pvHCChunk)[idx] + ((iPage << PAGE_SHIFT) & PGM_DYNAMIC_CHUNK_OFFSET_MASK) + off);
return VINF_SUCCESS;
return VERR_INVALID_POINTER;
return rc;
return rc;
return rc;
PGMDECL(int) PGMPhysGCPtr2HCPtrByGstCR3(PVM pVM, RTGCPTR GCPtr, uint32_t cr3, unsigned fFlags, PRTHCPTR pHCPtr)
int rc;
rc = PGMPhysGCPhys2HCPtr(pVM, (Pde.u & X86_PDE4M_PG_MASK) | ((RTGCUINTPTR)GCPtr & X86_PAGE_4M_OFFSET_MASK), pHCPtr);
return PGMPhysGCPhys2HCPtr(pVM, (Pte.u & X86_PTE_PG_MASK) | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), pHCPtr);
rc = PGMPhysGCPhys2HCPtr(pVM, (Pde.u & X86_PDE4M_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & X86_PAGE_4M_OFFSET_MASK), pHCPtr);
return PGMPhysGCPhys2HCPtr(pVM, (Pte.u & X86_PTE_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), pHCPtr);
return rc;
#ifdef IN_RING3
#ifdef IN_RING3
bool fGrabbedLock = false;
if (cbRead == 0)
#ifdef IN_RING3
fGrabbedLock = true;
int rc;
#ifdef IN_RING3
if (fGrabbedLock)
PGMPhysRead(pVM, GCPhys, pvBuf, cbRead); /* try again; can't assume pCur is still valid (paranoia) */
goto end;
switch (HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM))
case MM_RAM_FLAGS_ROM:
#ifdef IN_GC
goto end;
case MM_RAM_FLAGS_RESERVED:
goto end;
PPGMPHYSHANDLER pNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
#ifdef IN_GC
goto end;
goto end;
case MM_RAM_FLAGS_VIRTUAL_ALL:
unsigned iPage;
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
#ifdef IN_GC
goto end;
goto end;
goto end;
AssertReleaseMsgFailed(("Unknown read at %VGp size %d implement the complex physical reading case %x\n",
HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM)));
if ( !pCur
goto end;
end:
#ifdef IN_RING3
if (fGrabbedLock)
#ifdef IN_RING3
bool fGrabbedLock = false;
if (cbWrite == 0)
#ifdef IN_RING3
fGrabbedLock = true;
int rc;
#ifdef IN_RING3
if (fGrabbedLock)
PGMPhysWrite(pVM, GCPhys, pvBuf, cbWrite); /* try again; can't assume pCur is still valid (paranoia) */
goto end;
switch (HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_VIRTUAL_WRITE | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_PHYSICAL_WRITE))
case MM_RAM_FLAGS_MMIO2:
#ifdef IN_GC
goto end;
case MM_RAM_FLAGS_RESERVED:
goto end;
PPGMPHYSHANDLER pNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
rc = pNode->pfnHandlerR3(pVM, GCPhys, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, pNode->pvUserR3);
#ifdef IN_GC
goto end;
goto end;
case MM_RAM_FLAGS_VIRTUAL_ALL:
#ifdef IN_RING3
unsigned iPage;
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
#ifdef IN_GC
goto end;
goto end;
PPGMPHYSHANDLER pPhysNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
rc = pPhysNode->pfnHandlerR3(pVM, GCPhys, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, pPhysNode->pvUserR3);
unsigned iPage;
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
rc2 = pVirtNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, 0);
#ifdef IN_GC
goto end;
goto end;
goto end;
AssertReleaseMsgFailed(("Unknown write at %VGp size %d implement the complex physical writing case %x\n",
(HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_VIRTUAL_WRITE | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_PHYSICAL_WRITE))));
if ( !pCur
goto end;
end:
#ifdef IN_RING3
if (fGrabbedLock)
if (!cb)
return VINF_SUCCESS;
pRam;
void *pvSrc;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_PGM_PHYS_PAGE_RESERVED;
if (!cb)
return VINF_SUCCESS;
pRam;
void *pvDst;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_PGM_PHYS_PAGE_RESERVED;
if (!cb)
return VINF_SUCCESS;
void *pvSrc;
return rc;
return VINF_SUCCESS;
void *pvSrc;
return rc;
return VINF_SUCCESS;
if (!cb)
return VINF_SUCCESS;
void *pvDst;
return rc;
return VINF_SUCCESS;
void *pvDst;
return rc;
return VINF_SUCCESS;
if (!cb)
return VINF_SUCCESS;
void *pvDst;
return rc;
rc = PGMGstModifyPage(pVM, GCPtrDst, cb, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
return VINF_SUCCESS;
void *pvDst;
return rc;
return VINF_SUCCESS;
PGMDECL(int) PGMPhysInterpretedRead(PVM pVM, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb)
int rc;
void *pvSrc;
switch (rc)
case VINF_SUCCESS:
Log(("PGMPhysInterpretedRead: pvDst=%p pvSrc=%p cb=%d\n", pvDst, (uint8_t *)pvSrc + (GCPtrSrc & PAGE_OFFSET_MASK), cb));
return rc;
return VINF_SUCCESS;
void *pvSrc1;
switch (rc)
case VINF_SUCCESS:
return rc;
void *pvSrc2;
switch (rc)
case VINF_SUCCESS:
return rc;
return VINF_SUCCESS;
switch (rc)
case VINF_SUCCESS:
case VERR_PAGE_NOT_PRESENT:
return rc;