PGMAll.cpp revision 8cc5fcd8d00ac5e7e66de8b9abbf5e1f77b2b577
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * PGM - Page Manager and Monitor - All context code.
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * available from http://www.virtualbox.org. This file is free software;
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * General Public License (GPL) as published by the Free Software
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * additional information or have any questions.
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync/*******************************************************************************
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync* Header Files *
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync*******************************************************************************/
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync/*******************************************************************************
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync* Structures and Typedefs *
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync*******************************************************************************/
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * Stated structure for PGM_GST_NAME(HandlerVirtualUpdate) that's
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * passed to PGM_GST_NAME(VirtHandlerUpdateOne) during enumeration.
b0dfb334954c0552bb583967a3077ec88fd00471vboxsynctypedef struct PGMHVUSTATE
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync /** The VM handle. */
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync /** The todo flags. */
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync /** The CR4 register value. */
50f0e2e83362e100d306a411980d555d46aa00a8vboxsync/*******************************************************************************
50f0e2e83362e100d306a411980d555d46aa00a8vboxsync* Internal Functions *
50f0e2e83362e100d306a411980d555d46aa00a8vboxsync*******************************************************************************/
54828795a553ed0731f308ebda81675ad2c39d58vboxsyncDECLINLINE(int) pgmShwGetLongModePDPtr(PVM pVM, RTGCPTR64 GCPtr, PX86PML4E *ppPml4e, PX86PDPT *ppPdpt, PX86PDPAE *ppPD);
b0dfb334954c0552bb583967a3077ec88fd00471vboxsyncDECLINLINE(int) pgmShwGetPAEPDPtr(PVM pVM, RTGCPTR GCPtr, PX86PDPT *ppPdpt, PX86PDPAE *ppPD);
b0dfb334954c0552bb583967a3077ec88fd00471vboxsyncDECLINLINE(int) pgmShwGetPaePoolPagePD(PPGM pPGM, RTGCPTR GCPtr, PPGMPOOLPAGE *ppShwPde);
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync * Shadow - 32-bit mode
50f0e2e83362e100d306a411980d555d46aa00a8vboxsync/* Guest - real mode */
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_32BIT_REAL(name)
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync#define BTH_PGMPOOLKIND_PT_FOR_PT PGMPOOLKIND_32BIT_PT_FOR_PHYS
b0dfb334954c0552bb583967a3077ec88fd00471vboxsync#define BTH_PGMPOOLKIND_ROOT PGMPOOLKIND_32BIT_PD_PHYS
80523be8dba75b5eb32569fd72ddf54f3b009025vboxsync/* Guest - protected mode */
80523be8dba75b5eb32569fd72ddf54f3b009025vboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_32BIT_PROT(name)
80523be8dba75b5eb32569fd72ddf54f3b009025vboxsync#define BTH_PGMPOOLKIND_PT_FOR_PT PGMPOOLKIND_32BIT_PT_FOR_PHYS
80523be8dba75b5eb32569fd72ddf54f3b009025vboxsync#define BTH_PGMPOOLKIND_ROOT PGMPOOLKIND_32BIT_PD_PHYS
80523be8dba75b5eb32569fd72ddf54f3b009025vboxsync/* Guest - 32-bit mode */
8d29e9dc0d280b7b26834132b9ce14a3a845a7fdvboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_32BIT_32BIT(name)
8d29e9dc0d280b7b26834132b9ce14a3a845a7fdvboxsync#define BTH_PGMPOOLKIND_PT_FOR_PT PGMPOOLKIND_32BIT_PT_FOR_32BIT_PT
8d29e9dc0d280b7b26834132b9ce14a3a845a7fdvboxsync#define BTH_PGMPOOLKIND_PT_FOR_BIG PGMPOOLKIND_32BIT_PT_FOR_32BIT_4MB
8d29e9dc0d280b7b26834132b9ce14a3a845a7fdvboxsync * Shadow - PAE mode
8d29e9dc0d280b7b26834132b9ce14a3a845a7fdvboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_PAE_REAL(name)
b60e4b0625949fd68ed97f1353e2174c5b3192e5vboxsync/* Guest - real mode */
8d29e9dc0d280b7b26834132b9ce14a3a845a7fdvboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_PAE_REAL(name)
8d29e9dc0d280b7b26834132b9ce14a3a845a7fdvboxsync#define BTH_PGMPOOLKIND_PT_FOR_PT PGMPOOLKIND_PAE_PT_FOR_PHYS
8d29e9dc0d280b7b26834132b9ce14a3a845a7fdvboxsync#define BTH_PGMPOOLKIND_ROOT PGMPOOLKIND_PAE_PDPT_PHYS
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync/* Guest - protected mode */
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_PAE_PROT(name)
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define BTH_PGMPOOLKIND_PT_FOR_PT PGMPOOLKIND_PAE_PT_FOR_PHYS
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define BTH_PGMPOOLKIND_ROOT PGMPOOLKIND_PAE_PDPT_PHYS
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync/* Guest - 32-bit mode */
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_PAE_32BIT(name)
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define BTH_PGMPOOLKIND_PT_FOR_PT PGMPOOLKIND_PAE_PT_FOR_32BIT_PT
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define BTH_PGMPOOLKIND_PT_FOR_BIG PGMPOOLKIND_PAE_PT_FOR_32BIT_4MB
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define BTH_PGMPOOLKIND_ROOT PGMPOOLKIND_PAE_PDPT_FOR_32BIT
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync/* Guest - PAE mode */
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_PAE_PAE(name)
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define BTH_PGMPOOLKIND_PT_FOR_PT PGMPOOLKIND_PAE_PT_FOR_PAE_PT
64e0c74b525c440a571ce06f3eb6234d75913d76vboxsync#define BTH_PGMPOOLKIND_PT_FOR_BIG PGMPOOLKIND_PAE_PT_FOR_PAE_2MB
# include "PGMAllShw.h"
# include "PGMAllBth.h"
# ifdef VBOX_WITH_64_BITS_GUESTS
# include "PGMAllGst.h"
# include "PGMAllBth.h"
# include "PGMAllShw.h"
# include "PGMAllBth.h"
# include "PGMAllBth.h"
# include "PGMAllBth.h"
# include "PGMAllBth.h"
# ifdef VBOX_WITH_64_BITS_GUESTS
# include "PGMAllBth.h"
# include "PGMAllShw.h"
# include "PGMAllBth.h"
# include "PGMAllBth.h"
# include "PGMAllBth.h"
# include "PGMAllBth.h"
# ifdef VBOX_WITH_64_BITS_GUESTS
# include "PGMAllBth.h"
#ifndef IN_RING3
LogFlow(("PGMTrap0eHandler: uErr=%RGu pvFault=%RGv eip=%RGv\n", uErr, pvFault, (RTGCPTR)pRegFrame->rip));
#ifdef VBOX_WITH_STATISTICS
STAM_STATS({ if (rc == VINF_EM_RAW_GUEST_TRAP) STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eGuestPF); });
return rc;
return rc;
while (pMapping)
return pMapping;
return NULL;
* @param fAccess Access type (r/w, user/supervisor (X86_PTE_*))
return VERR_INVALID_PARAMETER;
return VINF_EM_RAW_GUEST_TRAP;
Log(("PGMIsValidAccess: access violation for %RGv attr %#llx vs %d:%d\n", Addr, fPage, fWrite, fUser));
return VINF_EM_RAW_GUEST_TRAP;
return PGMIsValidAccess(pVM, Addr + PAGE_SIZE, (cbSize > PAGE_SIZE) ? cbSize - PAGE_SIZE : 1, fAccess);
return rc;
* @param fAccess Access type (r/w, user/supervisor (X86_PTE_*))
AssertMsg(!(fAccess & ~(X86_PTE_US | X86_PTE_RW)), ("PGMVerifyAccess: invalid access type %08x\n", fAccess));
return VINF_EM_RAW_GUEST_TRAP;
Log(("PGMVerifyAccess: access violation for %RGv attr %#llx vs %d:%d\n", Addr, fPageGst, fWrite, fUser));
return VINF_EM_RAW_GUEST_TRAP;
return rc;
return VINF_EM_RAW_GUEST_TRAP;
return rc;
int rc;
#ifndef IN_RING3
return rc;
#ifdef IN_RC
return VINF_PGM_SYNC_CR3;
return VINF_EM_RAW_EMULATE_INSTR;
#ifdef IN_RING3
#ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY
return rc;
return rc;
return VINF_SUCCESS;
int rc;
return VINF_PGM_SYNC_CR3;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef IN_RC
int pgmShwSyncLongModePDPtr(PVM pVM, RTGCPTR64 GCPtr, PX86PML4E pGstPml4e, PX86PDPE pGstPdpe, PX86PDPAE *ppPD)
int rc;
if (!fNestedPaging)
return VINF_PGM_SYNC_CR3;
if (!fNestedPaging)
rc = pgmPoolAlloc(pVM, pGstPdpe->u & X86_PDPE_PG_MASK, PGMPOOLKIND_64BIT_PD_FOR_64BIT_PD, pShwPage->idx, iPdPt, &pShwPage);
rc = pgmPoolAlloc(pVM, GCPdPt + RT_BIT_64(62) /* hack: make the address unique */, PGMPOOLKIND_64BIT_PD_FOR_PHYS, pShwPage->idx, iPdPt, &pShwPage);
return VINF_PGM_SYNC_CR3;
return VINF_SUCCESS;
DECLINLINE(int) pgmShwGetLongModePDPtr(PVM pVM, RTGCPTR64 GCPtr, PX86PML4E *ppPml4e, PX86PDPT *ppPdpt, PX86PDPAE *ppPD)
if (ppPml4e)
return VERR_PAGE_MAP_LEVEL4_NOT_PRESENT;
return VINF_SUCCESS;
int rc;
rc = pgmPoolAlloc(pVM, GCPml4, PGMPOOLKIND_EPT_PDPT_FOR_PHYS, PGMPOOL_IDX_NESTED_ROOT, iPml4, &pShwPage);
rc = pgmPoolAlloc(pVM, GCPml4 + RT_BIT_64(63) /* hack: make the address unique */, PGMPOOLKIND_EPT_PDPT_FOR_PHYS, PGMPOOL_IDX_NESTED_ROOT, iPml4, &pShwPage);
return VINF_PGM_SYNC_CR3;
if (ppPdpt)
rc = pgmPoolAlloc(pVM, GCPdPt + RT_BIT_64(62) /* hack: make the address unique */, PGMPOOLKIND_64BIT_PD_FOR_PHYS, pShwPage->idx, iPdPt, &pShwPage);
return VINF_PGM_SYNC_CR3;
return VINF_SUCCESS;
return rc;
switch (enmShadowMode)
case PGMMODE_EPT:
switch (enmShadowMode)
case PGMMODE_32_BIT:
case PGMMODE_PAE:
case PGMMODE_PAE_NX:
case PGMMODE_AMD64:
case PGMMODE_AMD64_NX:
case PGMMODE_EPT:
case PGMMODE_NESTED:
switch (enmShadowMode)
case PGMMODE_32_BIT:
case PGMMODE_PAE:
case PGMMODE_PAE_NX:
case PGMMODE_AMD64:
case PGMMODE_AMD64_NX:
case SUPPAGINGMODE_32_BIT:
case SUPPAGINGMODE_PAE:
case SUPPAGINGMODE_PAE_GLOBAL:
case SUPPAGINGMODE_PAE_NX:
case SUPPAGINGMODE_AMD64:
case SUPPAGINGMODE_AMD64_NX:
case PGMMODE_32_BIT:
case PGMMODE_PAE:
case PGMMODE_PAE_NX:
case PGMMODE_AMD64:
case PGMMODE_AMD64_NX:
case PGMMODE_EPT:
case PGMMODE_NESTED:
if (fGlobal)
#ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY
if (fGlobal)
#ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY
if (fGlobal)
return rc;
return rc;
int rc;
return VINF_SUCCESS;
fGlobal = true;
#ifdef PGMPOOL_WITH_MONITORING
return rc;
#ifdef IN_RING3
return rc;
#ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY
return rc;
return VINF_SUCCESS;
#ifdef IN_RING3
return VINF_PGM_CHANGE_MODE;
case SUPPAGINGMODE_32_BIT:
return PGMMODE_32_BIT;
case SUPPAGINGMODE_PAE:
case SUPPAGINGMODE_PAE_GLOBAL:
return PGMMODE_PAE;
case SUPPAGINGMODE_PAE_NX:
return PGMMODE_PAE_NX;
case SUPPAGINGMODE_AMD64:
return PGMMODE_AMD64;
case SUPPAGINGMODE_AMD64_NX:
return PGMMODE_AMD64_NX;
return PGMMODE_INVALID;
switch (enmMode)
#ifdef IN_RC
return rc;
if (!pRam)
return VINF_SUCCESS;
if (!pRam)
return VINF_SUCCESS;
# ifdef IN_RC
register unsigned iCache;
static const uint8_t au8Trans[MM_HYPER_DYNAMIC_SIZE >> PAGE_SHIFT][RT_ELEMENTS(pVM->pgm.s.aHCPhysDynPageMapCache)] =
return VINF_SUCCESS;
# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
iPage++;
pVM->pgm.s.aHCPhysDynPageMapCache[iPage & (RT_ELEMENTS(pVM->pgm.s.aHCPhysDynPageMapCache) - 1)] = HCPhys;
return VINF_SUCCESS;
unsigned iPage;
Assert(GCPage >= pVM->pgm.s.pbDynPageMapBaseGC && GCPage < (pVM->pgm.s.pbDynPageMapBaseGC + MM_HYPER_DYNAMIC_SIZE));
return VINF_SUCCESS;
unsigned iPage;
Assert(GCPage >= pVM->pgm.s.pbDynPageMapBaseGC && GCPage < (pVM->pgm.s.pbDynPageMapBaseGC + MM_HYPER_DYNAMIC_SIZE));
return VINF_SUCCESS;
# ifdef VBOX_STRICT
#ifdef VBOX_STRICT
unsigned cErrors = 0;
cErrors++;
return cErrors;
return cErrors;