PGMAllPhys.cpp revision 4191d24ede3a8cc5fe066273422dcc2eadbd6ac2
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * PGM - Page Manager and Monitor, Physical Memory Addressing.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Copyright (C) 2006-2007 innotek GmbH
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * available from http://www.virtualbox.org. This file is free software;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * you can redistribute it and/or modify it under the terms of the GNU
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * General Public License (GPL) as published by the Free Software
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** @def PGM_IGNORE_RAM_FLAGS_RESERVED
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Don't respect the MM_RAM_FLAGS_RESERVED flag when converting to HC addresses.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Since this flag is currently incorrectly kept set for ROM regions we will
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * have to ignore it for now so we don't break stuff.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @todo this has been fixed now I believe, remove this hack.
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync/*******************************************************************************
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync* Header Files *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync*******************************************************************************/
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * \#PF Handler callback for Guest ROM range write access.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * We simply ignore the writes or fall back to the recompiler if we don't support the instruction.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns VBox status code (appropritate for trap handling and GC return).
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM VM Handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param uErrorCode CPU Error code.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pRegFrame Trap register frame.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pvFault The fault address (cr2).
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param GCPhysFault The GC physical address corresponding to pvFault.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pvUser User argument. Pointer to the ROM range structure.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncPGMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, void *pvFault, RTGCPHYS GCPhysFault, void *pvUser)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * If it's a simple instruction which doesn't change the cpu state
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * we will simply skip it. Otherwise we'll have to defer it to REM.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = EMInterpretDisasOne(pVM, pRegFrame, &Cpu, &cbOp);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync && !(Cpu.prefix & (PREFIX_REPNE | PREFIX_REP | PREFIX_SEG)))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** @todo Find other instructions we can safely skip, possibly
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * adding this kind of detection to DIS or EM. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCGuestROMWriteHandled);
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync rc = PGMHandlerPhysicalPageTempOff(pVM, pRom->GCPhys, GCPhysFault & X86_PTE_PG_MASK);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* Handle it in ring-3 because it's *way* easier there. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhysFault=%RGp\n",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCGuestROMWriteUnhandled);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#endif /* IN_RING3 */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Checks if Address Gate 20 is enabled or not.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns true if enabled.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns false if disabled.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM VM handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync LogFlow(("PGMPhysIsA20Enabled %d\n", pVM->pgm.s.fA20Enabled));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return !!pVM->pgm.s.fA20Enabled ; /* stupid MS compiler doesn't trust me. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Validates a GC physical address.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns true if valid.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns false if invalid.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM The VM handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param GCPhys The physical address to validate.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncPGMDECL(bool) PGMPhysIsGCPhysValid(PVM pVM, RTGCPHYS GCPhys)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Checks if a GC physical address is a normal page,
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * i.e. not ROM, MMIO or reserved.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns true if normal.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns false if invalid, ROM, MMIO or reserved page.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM The VM handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param GCPhys The physical address to check.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncPGMDECL(bool) PGMPhysIsGCPhysNormal(PVM pVM, RTGCPHYS GCPhys)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync && !(pPage->HCPhys & (MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO2));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Converts a GC physical address to a HC physical address.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns VINF_SUCCESS on success.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * page but has no physical backing.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * GC physical address.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM The VM handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param GCPhys The GC physical address to convert.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pHCPhys Where to store the HC physical address on success.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncPGMDECL(int) PGMPhysGCPhys2HCPhys(PVM pVM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (RT_UNLIKELY(pPage->HCPhys & MM_RAM_FLAGS_RESERVED)) /** @todo PAGE FLAGS */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *pHCPhys = PGM_PAGE_GET_HCPHYS(pPage) | (GCPhys & PAGE_OFFSET_MASK);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Invalidates the GC page mapping TLB.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM The VM handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncPDMDECL(void) PGMPhysInvalidatePageGCMapTLB(PVM pVM)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* later */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Invalidates the ring-0 page mapping TLB.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM The VM handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncPDMDECL(void) PGMPhysInvalidatePageR0MapTLB(PVM pVM)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Invalidates the ring-3 page mapping TLB.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM The VM handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncPDMDECL(void) PGMPhysInvalidatePageR3MapTLB(PVM pVM)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.PhysTlbHC.aEntries); i++)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVM->pgm.s.PhysTlbHC.aEntries[i].GCPhys = NIL_RTGCPHYS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Makes sure that there is at least one handy page ready for use.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * This will also take the appropriate actions when reaching water-marks.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns The following VBox status codes.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @retval VINF_SUCCESS on success.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @retval VERR_EM_NO_MEMORY if we're really out of memory.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM The VM handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @remarks Must be called from within the PGM critical section. It may
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * nip back to ring-3/0 in some cases.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** @remarks
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * low-water mark logic for R0 & GC:
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * - 75%: Set FF.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * - 50%: Force return to ring-3 ASAP.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * For ring-3 there is a little problem wrt to the recompiler, so:
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * - 75%: Set FF.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * - 50%: Try allocate pages; on failure we'll force REM to quite ASAP.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The basic idea is that we should be able to get out of any situation with
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * only 50% of handy pages remaining.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * At the moment we'll not adjust the number of handy pages relative to the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * actual VM RAM committment, that's too much work for now.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(pVM->pgm.s.cHandyPages <= RT_ELEMENTS(pVM->pgm.s.aHandyPages));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync || pVM->pgm.s.cHandyPages - 1 <= RT_ELEMENTS(pVM->pgm.s.aHandyPages) / 2 /* 50% */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Log(("PGM: cHandyPages=%u out of %u -> allocate more\n", pVM->pgm.s.cHandyPages - 1 <= RT_ELEMENTS(pVM->pgm.s.aHandyPages)));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES, 0, NULL);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** @todo call PGMR0PhysAllocateHandyPages directly - need to make sure we can call kernel code first and deal with the seeding fallback. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VMMR0CallHost(pVM, VMMCALLHOST_PGM_ALLOCATE_HANDY_PAGES, 0);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VMMGCCallHost(pVM, VMMCALLHOST_PGM_ALLOCATE_HANDY_PAGES, 0);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(VM_FF_ISSET(pVM, VM_FF_PGM_NEED_HANDY_PAGES));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(pVM->pgm.s.cHandyPages <= RT_ELEMENTS(pVM->pgm.s.aHandyPages));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync else if (pVM->pgm.s.cHandyPages - 1 <= (RT_ELEMENTS(pVM->pgm.s.aHandyPages) / 4) * 3) /* 75% */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (pVM->pgm.s.cHandyPages - 1 <= RT_ELEMENTS(pVM->pgm.s.aHandyPages) / 2)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Log(("PGM: VM_FF_TO_R3 - cHandyPages=%u out of %u\n", pVM->pgm.s.cHandyPages - 1 <= RT_ELEMENTS(pVM->pgm.s.aHandyPages)));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Replace a zero or shared page with new page that we can write to.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns The following VBox status codes.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @retval VINF_SUCCESS on success, pPage is modified.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @retval VERR_EM_NO_MEMORY if we're totally out of memory.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @todo Propagate VERR_EM_NO_MEMORY up the call tree.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM The VM address.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pPage The physical page tracking structure. This will
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * be modified on success.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param GCPhys The address of the page.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @remarks Must be called from within the PGM critical section. It may
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * nip back to ring-3/0 in some cases.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @remarks This function shouldn't really fail, however if it does
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * it probably means we've screwed up the size of the amount
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * and/or the low-water mark of handy pages. Or, that some
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * device I/O is causing a lot of pages to be allocated while
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * while the host is in a low-memory condition.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncint pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Ensure that we've got a page handy, take it and use it.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertMsg(PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_SHARED(pPage), ("%d %RGp\n", PGM_PAGE_GET_STATE(pPage), GCPhys));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(iHandyPage < RT_ELEMENTS(pVM->pgm.s.aHandyPages));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys != NIL_RTHCPHYS);
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync Assert(!(pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys & ~X86_PTE_PAE_PG_MASK));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(pVM->pgm.s.aHandyPages[iHandyPage].idPage != NIL_GMM_PAGEID);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(pVM->pgm.s.aHandyPages[iHandyPage].idSharedPage == NIL_GMM_PAGEID);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * There are one or two action to be taken the next time we allocate handy pages:
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * - Tell the GMM (global memory manager) what the page is being used for.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * (Speeds up replacement operations - sharing and defragmenting.)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * - If the current backing is shared, it must be freed.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync const RTHCPHYS HCPhys = pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys = GCPhys;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVM->pgm.s.aHandyPages[iHandyPage].idSharedPage = PGM_PAGE_GET_PAGEID(pPage);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(PGM_PAGE_GET_PAGEID(pPage) != NIL_GMM_PAGEID);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Log2(("PGM: Replaced shared page %#x at %RGp with %#x / %RHp\n", PGM_PAGE_GET_PAGEID(pPage),
956a0e3c076406b83d635174a201fd8761ee5133vboxsync GCPhys, pVM->pgm.s.aHandyPages[iHandyPage].idPage, HCPhys));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatPageReplaceShared);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** @todo err.. what about copying the page content? */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Log2(("PGM: Replaced zero page %RGp with %#x / %RHp\n", GCPhys, pVM->pgm.s.aHandyPages[iHandyPage].idPage, HCPhys));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** @todo verify that the handy page is zero! */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Do the PGMPAGE modifications.
return VINF_SUCCESS;
case PGM_PAGE_STATE_ALLOCATED:
return VINF_SUCCESS;
case PGM_PAGE_STATE_ZERO:
return VERR_PGM_PHYS_PAGE_RESERVED;
case PGM_PAGE_STATE_SHARED:
#ifdef IN_GC
if (!pMap)
#ifdef IN_RING0
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef IN_GC
if (!pRam)
void *pv;
return rc;
return VINF_SUCCESS;
#ifdef VBOX_WITH_NEW_PHYS_CODE
#ifdef IN_GC
return rc;
# ifdef IN_GC
PGMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGMPAGEMAPLOCK pLock)
return rc;
PGMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void const **ppv, PPGMPAGEMAPLOCK pLock)
return rc;
#ifdef VBOX_WITH_NEW_PHYS_CODE
#ifdef IN_GC
#ifdef VBOX_WITH_NEW_PHYS_CODE
return rc;
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VERR_PGM_PHYS_PAGE_RESERVED;
*pHCPtr = (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pavHCChunk)[iChunk] + (off & PGM_DYNAMIC_CHUNK_OFFSET_MASK));
return VERR_PGM_PHYS_PAGE_RESERVED;
return VINF_SUCCESS;
return rc;
return rc;
#ifdef VBOX_WITH_NEW_PHYS_CODE
rc = PGMPhysGCPhys2HCPtr(pVM, GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return rc;
PGMDECL(int) PGMPhysGCPtr2HCPtrByGstCR3(PVM pVM, RTGCPTR GCPtr, uint32_t cr3, unsigned fFlags, PRTHCPTR pHCPtr)
#ifdef VBOX_WITH_NEW_PHYS_CODE
int rc;
rc = PGMPhysGCPhys2HCPtr(pVM, (Pde.u & X86_PDE4M_PG_MASK) | ((RTGCUINTPTR)GCPtr & X86_PAGE_4M_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return PGMPhysGCPhys2HCPtr(pVM, (Pte.u & X86_PTE_PG_MASK) | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
rc = PGMPhysGCPhys2HCPtr(pVM, (Pde.u & X86_PDE4M_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & X86_PAGE_4M_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return PGMPhysGCPhys2HCPtr(pVM, (Pte.u & X86_PTE_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return rc;
#ifdef IN_RING3
#ifdef IN_RING3
bool fGrabbedLock = false;
if (cbRead == 0)
#ifdef IN_RING3
fGrabbedLock = true;
goto end;
switch (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM)) /** @todo PAGE FLAGS */
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",
pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM))); /** @todo PAGE FLAGS */
if ( !pRam
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 pRam is still valid (paranoia) */
goto end;
switch (pPage->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)) /** @todo PAGE FLAGS */
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",
(pPage->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)))); /** @todo PAGE FLAGS */
if ( !pRam
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;
#ifdef VBOX_WITH_NEW_PHYS_CODE
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;
int rc;
if (!cb)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
int rc;
if (!cb)
return VINF_SUCCESS;
return VINF_SUCCESS;
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;