PGMAllMap.cpp revision 38682879fd947e2d3bf5565d6ccf16980a7a36d9
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * PGM - Page Manager and Monitor - All context code.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * available from http://www.virtualbox.org. This file is free software;
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * General Public License (GPL) as published by the Free Software
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * additional information or have any questions.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync/*******************************************************************************
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync* Header Files *
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync*******************************************************************************/
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * Maps a range of physical pages at a given virtual address
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * in the guest context.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * The GC virtual address range must be within an existing mapping.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * @returns VBox status code.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * @param pVM The virtual machine.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * @param GCPtr Where to map the page(s). Must be page aligned.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * @param HCPhys Start of the range of physical pages. Must be page aligned.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * @param cbPages Number of bytes to map. Must be page aligned.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * @param fFlags Page flags (X86_PTE_*).
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsyncVMMDECL(int) PGMMap(PVM pVM, RTGCUINTPTR GCPtr, RTHCPHYS HCPhys, uint32_t cbPages, unsigned fFlags)
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync * Validate input.
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync AssertMsg(RT_ALIGN_T(GCPtr, PAGE_SIZE, RTGCUINTPTR) == GCPtr, ("Invalid alignment GCPtr=%#x\n", GCPtr));
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync AssertMsg(cbPages > 0 && RT_ALIGN_32(cbPages, PAGE_SIZE) == cbPages, ("Invalid cbPages=%#x\n", cbPages));
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync AssertMsg(!(fFlags & X86_PDE_PG_MASK), ("Invalid flags %#x\n", fFlags));
5e91fc5e5ea9cccb7a40636f73253d489fbe340bvboxsync /* hypervisor defaults */
while (pCur)
return VERR_INVALID_PARAMETER;
pCur->aPTs[iPT].CTX_SUFF(pPT)->a[iPageNo].u = (uint32_t)Pte.u; /* ASSUMES HCPhys < 4GB and/or that we're never gonna do 32-bit on a PAE host! */
if (!cbPages)
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
while (pCur)
while (cb > 0)
iPTE++;
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
#ifndef IN_RING0
Log4(("pgmMapSetShadowPDEs new pde %x (mappings enabled %d)\n", iNewPDE, pgmMapAreMappingsEnabled(&pVM->pgm.s)));
iNewPDE += i;
iNewPDE--;
switch(enmShadowMode)
case PGMMODE_32_BIT:
pgmPoolFree(pVM, pShw32BitPd->a[iNewPDE].u & X86_PDE_PG_MASK, pVM->pgm.s.CTX_SUFF(pShwPageCR3)->idx, iNewPDE);
/* Default mapping page directory flags are read/write and supervisor; individual page attributes determine the final flags */
Pde.u = PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPT;
case PGMMODE_PAE:
case PGMMODE_PAE_NX:
if (!pShwPaePd)
GstPdpe.u = X86_PDPE_P; /* rw/us are reserved for PAE pdpte's; accessed bit causes invalid VT-x guest state errors */
if (pGstPdpe)
GstPdpe.u = X86_PDPE_P; /* rw/us are reserved for PAE pdpte's; accessed bit causes invalid VT-x guest state errors */
PdePae0.u = PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT0;
iPDE++;
PdePae1.u = PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT1;
AssertFailed();
Log(("pgmMapClearShadowPDEs old pde %x (mappings enabled %d)\n", iOldPDE, pgmMapAreMappingsEnabled(&pVM->pgm.s)));
iOldPDE += i;
iOldPDE--;
switch(enmShadowMode)
case PGMMODE_32_BIT:
case PGMMODE_PAE:
case PGMMODE_PAE_NX:
iPDE++;
/* Clear the PGM_PDFLAGS_MAPPING flag for the page directory pointer entry. (legacy PAE guest mode) */
AssertFailed();
iPDE += i;
iPDE--;
switch(enmShadowMode)
case PGMMODE_32_BIT:
AssertMsg(pShw32BitPd->a[iPDE].u == (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPT),
("Expected %x vs %x\n", pShw32BitPd->a[iPDE].u, (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPT)));
case PGMMODE_PAE:
case PGMMODE_PAE_NX:
AssertMsg(pShwPaePd->a[iPaePDE].u == (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT0),
("Expected %RX64 vs %RX64\n", pShwPaePd->a[iPDE].u, (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPaePT0)));
iPaePDE++;
AssertMsg(pShwPaePd->a[iPaePDE].u == (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT1),
("Expected %RX64 vs %RX64\n", pShwPaePd->a[iPDE].u, (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPaePT1)));
AssertFailed();
# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
#ifndef IN_RING0
return VINF_SUCCESS;
/* @note A log flush (in RC) can cause problems when called from MapCR3 (inconsistent state will trigger assertions). */
# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
return VINF_SUCCESS;
return VINF_SUCCESS;
# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
return VINF_SUCCESS;
while (iPT-- > 0)
#ifdef IN_RING3
while (iPT-- > 0)
#ifdef IN_RING3
AssertFailed();
# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
return VINF_SUCCESS;
while (iPT-- > 0)
#ifdef IN_RING3
return VINF_PGM_SYNC_CR3;
if (!pCur)
while (iPT-- > 0)
#ifdef IN_RING3
return VINF_PGM_SYNC_CR3;
if (!pCur)
AssertFailed();
return VINF_SUCCESS;