PGMAllShw.h revision d1011b3f539ad819b5e2c1c3d8152e7113725bf6
/* $Id$ */
/** @file
* VBox - Page Manager, Shadow Paging Template - All context code.
*/
/*
* Copyright (C) 2006 InnoTek Systemberatung GmbH
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License as published by the Free Software Foundation,
* in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
* distribution. VirtualBox OSE is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY of any kind.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
#if PGM_SHW_TYPE == PGM_TYPE_32BIT
# define SHW_PDE_PG_MASK X86_PDE_PG_MASK
# define SHW_PD_SHIFT X86_PD_SHIFT
# define SHW_PD_MASK X86_PD_MASK
# define SHW_TOTAL_PD_ENTRIES X86_PG_ENTRIES
# define SHW_PTE_PG_MASK X86_PTE_PG_MASK
# define SHW_PT_SHIFT X86_PT_SHIFT
# define SHW_PT_MASK X86_PT_MASK
# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_PD
#else
# define PSHWPTE PX86PTEPAE
# define PSHWPDE PX86PDEPAE
# define SHW_PDE_PG_MASK X86_PDE_PAE_PG_MASK
# define SHW_PD_SHIFT X86_PD_PAE_SHIFT
# define SHW_PD_MASK X86_PD_PAE_MASK
# define SHW_PTE_PG_MASK X86_PTE_PAE_PG_MASK
# define SHW_PT_SHIFT X86_PT_PAE_SHIFT
# define SHW_PT_MASK X86_PT_PAE_MASK
#if PGM_SHW_TYPE == PGM_TYPE_AMD64
# define SHW_PDPTR_SHIFT X86_PDPTR_SHIFT
# define SHW_PDPTR_MASK X86_PDPTR_MASK
# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_PML4
#else /* 32 bits PAE mode */
# define SHW_PDPTR_SHIFT X86_PDPTR_SHIFT
# define SHW_PDPTR_MASK X86_PDPTR_MASK_32
# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_PAE_PD
#endif
#endif
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
PGM_SHW_DECL(int, ModifyPage)(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask);
/**
* Gets effective page information (from the VMM page directory).
*
* @returns VBox status.
* @param pVM VM Handle.
* @param GCPtr Guest Context virtual address of the page.
* @param pfFlags Where to store the flags. These are X86_PTE_*.
* @param pHCPhys Where to store the HC physical address of the page.
* This is page aligned.
* @remark You should use PGMMapGetPage() for pages in a mapping.
*/
{
/*
* Get the PDE.
*/
#if PGM_SHW_TYPE == PGM_TYPE_AMD64
/*
* For the first 4G we have preallocated page directories.
* Since the two upper levels contains only fixed flags, we skip those when possible.
*/
#if GC_ARCH_BITS == 64
#endif
{
}
#if GC_ARCH_BITS == 64
else
{
/* PML4 */
return VERR_PAGE_TABLE_NOT_PRESENT;
/* PDPTR */
if (VBOX_FAILURE(rc))
return rc;
return VERR_PAGE_TABLE_NOT_PRESENT;
/* PD */
if (VBOX_FAILURE(rc))
return rc;
}
#endif /* GC_ARCH_BITS == 64 */
#else /* PGM_TYPE_32BIT */
#endif
return VERR_PAGE_TABLE_NOT_PRESENT;
/*
* Get PT entry.
*/
if (!(Pde.u & PGM_PDFLAGS_MAPPING))
{
if (VBOX_FAILURE(rc))
return rc;
}
else /* mapping: */
{
#if PGM_SHW_TYPE == PGM_TYPE_32BIT
#else /* PAE and AMD64: */
#endif
}
return VERR_PAGE_NOT_PRESENT;
/*
* Store the results.
* RW and US flags depend on the entire page transation hierarchy - except for
* legacy PAE which has a simplified PDPE.
*/
if (pfFlags)
if (pHCPhys)
return VINF_SUCCESS;
}
/**
* Modify page flags for a range of pages in the shadow context.
*
* The existing flags are ANDed with the fMask and ORed with the fFlags.
*
* @returns VBox status code.
* @param pVM VM handle.
* @param GCPtr Virtual address of the first page in the range. Page aligned!
* @param cb Size (in bytes) of the range to apply the modification to. Page aligned!
* @param fFlags The OR mask - page flags X86_PTE_*, excluding the page mask of course.
* @param fMask The AND mask - page flags X86_PTE_*.
* Be extremely CAREFUL with ~'ing values because they can be 32-bit!
* @remark You must use PGMMapModifyPage() for pages in a mapping.
*/
PGM_SHW_DECL(int, ModifyPage)(PVM pVM, RTGCUINTPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask)
{
/*
* Walk page tables and pages till we're done.
*/
for (;;)
{
/*
* Get the PDE.
*/
#if PGM_SHW_TYPE == PGM_TYPE_AMD64
/*
* For the first 4G we have preallocated page directories.
* Since the two upper levels contains only fixed flags, we skip those when possible.
*/
#if GC_ARCH_BITS == 64
#endif
{
}
#if GC_ARCH_BITS == 64
else
{
/* PML4 */
return VERR_PAGE_TABLE_NOT_PRESENT;
/* PDPTR */
if (VBOX_FAILURE(rc))
return rc;
return VERR_PAGE_TABLE_NOT_PRESENT;
/* PD */
if (VBOX_FAILURE(rc))
return rc;
}
#endif /* GC_ARCH_BITS == 64 */
#else /* PGM_TYPE_32BIT */
#endif
return VERR_PAGE_TABLE_NOT_PRESENT;
/*
* Map the page table.
*/
if (VBOX_FAILURE(rc))
return rc;
{
{
}
/* next page */
if (!cb)
return VINF_SUCCESS;
iPTE++;
}
}
}
/**
* Retrieve shadow PDE
*
* @returns VBox status code.
* @param pVM The virtual machine.
* @param iPD Shadow PDE index.
* @param pPde Where to store the shadow PDE entry.
*/
{
/*
* Get page directory addresses.
*/
# if PGM_SHW_TYPE == PGM_TYPE_32BIT
# else
PX86PDEPAE pPdeSrc = &CTXMID(pVM->pgm.s.ap,PaePDs)[0]->a[iPD]; /* We treat this as a PD with 2048 entries. */
# endif
return VINF_SUCCESS;
#else
AssertFailed();
return VERR_NOT_IMPLEMENTED;
#endif
}
/**
* Set shadow PDE
*
* @returns VBox status code.
* @param pVM The virtual machine.
* @param iPD Shadow PDE index.
* @param Pde Shadow PDE.
*/
{
/*
* Get page directory addresses and update the specified entry.
*/
# if PGM_SHW_TYPE == PGM_TYPE_32BIT
# else
PX86PDEPAE pPdeDst = &CTXMID(pVM->pgm.s.ap,PaePDs)[0]->a[iPD]; /* We treat this as a PD with 2048 entries. */
# endif
return VINF_SUCCESS;
#else
AssertFailed();
return VERR_NOT_IMPLEMENTED;
#endif
}
/**
* Modify shadow PDE
*
* @returns VBox status code.
* @param pVM The virtual machine.
* @param iPD Shadow PDE index.
* @param fFlags The OR mask - page flags X86_PDE_*, excluding the page mask of course.
* @param fMask The AND mask - page flags X86_PDE_*.
* Be extremely CAREFUL with ~'ing values because they can be 32-bit!
*/
{
/*
* Get page directory addresses and update the specified entry.
*/
# if PGM_SHW_TYPE == PGM_TYPE_32BIT
pPdeDst->u = ((pPdeDst->u & ((X86PGUINT)fMask | SHW_PDE_PG_MASK)) | ((X86PGUINT)fFlags & ~SHW_PDE_PG_MASK));
# else
PX86PDEPAE pPdeDst = &CTXMID(pVM->pgm.s.ap,PaePDs)[0]->a[iPD]; /* We treat this as a PD with 2048 entries. */
# endif
return VINF_SUCCESS;
#else
AssertFailed();
return VERR_NOT_IMPLEMENTED;
#endif
}