PGMAllGst.h revision 12abc2907ce8c96c9354ce01b08f175ad186475a
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * VBox - Page Manager, Guest Paging Template - All context code.
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * available from http://www.virtualbox.org. This file is free software;
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * you can redistribute it and/or modify it under the terms of the GNU
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * General Public License (GPL) as published by the Free Software
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * additional information or have any questions.
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync/*******************************************************************************
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync* Defined Constants And Macros *
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync*******************************************************************************/
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync# define GST_BIG_PAGE_OFFSET_MASK X86_PAGE_4M_OFFSET_MASK
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync# define GST_BIG_PAGE_OFFSET_MASK X86_PAGE_2M_OFFSET_MASK
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync# define GST_TOTAL_PD_ENTRIES (X86_PG_PAE_ENTRIES * X86_PG_PAE_PDPE_ENTRIES)
f1958d2f336573471dde3a866c66783221ab7fdbvboxsync# define GST_TOTAL_PD_ENTRIES (X86_PG_AMD64_ENTRIES * X86_PG_AMD64_PDPE_ENTRIES)
f1958d2f336573471dde3a866c66783221ab7fdbvboxsync/*******************************************************************************
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsync* Internal Functions *
f1958d2f336573471dde3a866c66783221ab7fdbvboxsync*******************************************************************************/
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsyncPGM_GST_DECL(int, GetPage)(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys);
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsyncPGM_GST_DECL(int, ModifyPage)(PVM pVM, RTGCUINTPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
f1958d2f336573471dde3a866c66783221ab7fdbvboxsyncPGM_GST_DECL(int, GetPDE)(PVM pVM, RTGCUINTPTR GCPtr, PX86PDEPAE pPDE);
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsyncPGM_GST_DECL(int, MapCR3)(PVM pVM, RTGCPHYS GCPhysCR3);
f1958d2f336573471dde3a866c66783221ab7fdbvboxsyncPGM_GST_DECL(int, MonitorCR3)(PVM pVM, RTGCPHYS GCPhysCR3);
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsyncPGM_GST_DECL(bool, HandlerVirtualUpdate)(PVM pVM, uint32_t cr4);
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsyncPGM_GST_DECL(int, WriteHandlerCR3)(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsyncPGM_GST_DECL(int, PAEWriteHandlerPD)(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsync * Gets effective Guest OS page information.
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsync * When GCPtr is in a big page, the function will return as if it was a normal
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsync * 4KB page. If the need for distinguishing between big and normal page becomes
f1958d2f336573471dde3a866c66783221ab7fdbvboxsync * necessary at a later point, a PGMGstGetPage Ex() will be created for that
9cd42f2598c236d3c5e47f3e5bf21d4e96f001edvboxsync * @returns VBox status.
f1958d2f336573471dde3a866c66783221ab7fdbvboxsync * @param pVM VM Handle.
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * @param GCPtr Guest Context virtual address of the page. Page aligned!
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * @param pfFlags Where to store the flags. These are X86_PTE_*, even for big pages.
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * @param pGCPhys Where to store the GC physical address of the page.
04008c8439b294c40e670b4ea71471fa71ef9d69vboxsync * This is page aligned. The fact that the
1b396f7f5a76d66e62fc9d8e66dcbe8e7bf72039vboxsyncPGM_GST_DECL(int, GetPage)(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)
#elif PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_PAE || PGM_GST_TYPE == PGM_TYPE_AMD64
return VERR_PAGE_TABLE_NOT_PRESENT;
return VERR_PAGE_TABLE_NOT_PRESENT;
return rc;
return VERR_PAGE_NOT_PRESENT;
if (pfFlags)
if (fNoExecuteBitValid)
if (pGCPhys)
if (pfFlags)
if (fNoExecuteBitValid)
if (pGCPhys)
*pGCPhys = (Pde.u & GST_PDE_BIG_PG_MASK) | (GCPtr & (~GST_PDE_BIG_PG_MASK ^ ~GST_PTE_PG_MASK)); /** @todo pse36 */
return VINF_SUCCESS;
return VERR_NOT_SUPPORTED;
PGM_GST_DECL(int, ModifyPage)(PVM pVM, RTGCUINTPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask)
if (!pPde)
return VERR_PAGE_TABLE_NOT_PRESENT;
/** @todo Setting the r/w, u/s & nx bits might have no effect depending on the pdpte & pml4 values */
if (!pPde)
return VERR_PAGE_TABLE_NOT_PRESENT;
return VERR_PAGE_TABLE_NOT_PRESENT;
return rc;
if (!cb)
return VINF_SUCCESS;
iPTE++;
Pde.u = (Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PS)) /** @todo pse36 */
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
int rc = pgmRamGCPhys2HCPtrAndHCPhysWithFlags(&pVM->pgm.s, GCPhysCR3 & GST_CR3_PAGE_MASK, &HCPtrGuestCR3, &HCPhysGuestCR3);
pVM->pgm.s.pGstPaePDPTGC = (RCPTRTYPE(PX86PDPT)) ((RCPTRTYPE(uint8_t *))pVM->pgm.s.GCPtrCR3Mapping + offset);
pgmPoolFreeByPage(pPool, pVM->pgm.s.pShwAmd64CR3, PGMPOOL_IDX_AMD64_CR3, pVM->pgm.s.pShwAmd64CR3->GCPhys >> PAGE_SHIFT);
rc = pgmPoolAlloc(pVM, GCPhysCR3, PGMPOOLKIND_ROOT_PML4, PGMPOOL_IDX_AMD64_CR3, GCPhysCR3 >> PAGE_SHIFT, &pVM->pgm.s.pShwAmd64CR3);
return VINF_PGM_SYNC_CR3;
return rc;
for (unsigned i=0; i < X86_PG_PAE_PDPE_ENTRIES; i++)
pgmPoolFreeByPage(pPool, pVM->pgm.s.pShwAmd64CR3, PGMPOOL_IDX_AMD64_CR3, pVM->pgm.s.pShwAmd64CR3->GCPhys >> PAGE_SHIFT);
return rc;
# ifndef PGMPOOL_WITH_MIXED_PT_CR3
rc = PGMHandlerPhysicalModify(pVM, pVM->pgm.s.GCPhysGstCR3Monitored, GCPhysCR3, GCPhysCR3 + cbCR3Stuff - 1);
rc = PGMHandlerPhysicalRegisterEx(pVM, PGMPHYSHANDLERTYPE_PHYSICAL_WRITE, GCPhysCR3, GCPhysCR3 + cbCR3Stuff - 1,
AssertMsgFailed(("PGMHandlerPhysicalModify/PGMR3HandlerPhysicalRegister failed, rc=%Rrc GCPhysGstCR3Monitored=%RGp GCPhysCR3=%RGp\n",
return rc;
# ifndef PGMPOOL_WITH_MIXED_PT_CR3
AssertFailed();
AssertMsgFailed(("PGMHandlerPhysicalModify/PGMR3HandlerPhysicalRegister failed, rc=%Rrc GCPhysGstCR3Monitored=%RGp GCPhysCR3=%RGp\n",
return rc;
for (unsigned i = 0; i < X86_PG_PAE_PDPE_ENTRIES; i++)
AssertMsgFailed(("PGMHandlerPhysicalModify/PGMR3HandlerPhysicalRegister failed, rc=%Rrc GCPhysGstCR3Monitored=%RGp GCPhysCR3=%RGp\n",
return rc;
return rc;
# ifndef PGMPOOL_WITH_MIXED_PT_CR3
: PGMPOOL_IDX_PD);
# ifndef PGMPOOL_WITH_MIXED_PT_CR3
AssertFailed();
for (unsigned i = 0; i < X86_PG_PAE_PDPE_ENTRIES; i++)
return rc;
* @param pvUser Pointer to a PGMVHUARGS structure (see PGM.cpp).
static DECLCALLBACK(int) PGM_GST_NAME(VirtHandlerUpdateOne)(PAVLROGCPTRNODECORE pNode, void *pvUser)
unsigned iPage = 0;
("{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} GCPhysNew=%VGp\n",
offPage = 0;
("{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} GCPhysNew=%VGp\n",
offPage = 0;
RTAvlroGCPtrDoWithAll(&pVM->pgm.s.CTXSUFF(pTrees)->VirtHandlers, true, PGM_GST_NAME(VirtHandlerUpdateOne), &State);
RTAvlroGCPtrDoWithAll(&pVM->pgm.s.CTXSUFF(pTrees)->VirtHandlers, true, pgmHandlerVirtualResetOne, pVM);
PGM_GST_DECL(int, WriteHandlerCR3)(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
#ifdef DEBUG
Log(("pgmXXGst32BitWriteHandlerCR3: emulated change to PD %#x addr=%VGv\n", iPD1, iPD1 << X86_PD_SHIFT));
Log(("pgmXXGst32BitWriteHandlerCR3: emulated change to PD %#x addr=%VGv\n", iPD2, iPD2 << X86_PD_SHIFT));
Log(("pgmXXGst32BitWriteHandlerCR3: detected conflict iPD1=%#x iPD2=%#x - returns %Rrc\n", iPD1, iPD2, rc));
return rc;
return rc;
PGM_GST_DECL(int, WriteHandlerCR3)(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
for (unsigned i = 0; i < X86_PG_PAE_PDPE_ENTRIES; i++)
return rc;
PGM_GST_DECL(int, WriteHandlerPD)(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
RTGCUINTPTR i;
for (i = 0; i < X86_PG_PAE_PDPE_ENTRIES; i++)
#ifdef DEBUG
return VINF_PGM_SYNC_CR3;
return rc;