PGMAllShw.h revision 5476bd9ec30ebad9ed9e39aa8a4ff2c49bede2d7
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VBox - Page Manager, Shadow Paging Template - All context code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2006-2007 innotek GmbH
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync */
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync/*******************************************************************************
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync* Defined Constants And Macros *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHWPT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef PSHWPT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHWPTE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef PSHWPTE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHWPD
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef PSHWPD
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHWPDE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef PSHWPDE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_PDE_PG_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_PD_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_PD_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_PTE_PG_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_PT_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_PT_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_TOTAL_PD_ENTRIES
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_PDPTR_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_PDPTR_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef SHW_POOL_ROOT_IDX
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if PGM_SHW_TYPE == PGM_TYPE_32BIT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHWPT X86PT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define PSHWPT PX86PT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHWPTE X86PTE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define PSHWPTE PX86PTE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHWPD X86PD
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define PSHWPD PX86PD
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHWPDE X86PDE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define PSHWPDE PX86PDE
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync# define SHW_PDE_PG_MASK X86_PDE_PG_MASK
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync# define SHW_PD_SHIFT X86_PD_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PD_MASK X86_PD_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_TOTAL_PD_ENTRIES X86_PG_ENTRIES
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PTE_PG_MASK X86_PTE_PG_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PT_SHIFT X86_PT_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PT_MASK X86_PT_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_PD
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHWPT X86PTPAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define PSHWPT PX86PTPAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHWPTE X86PTEPAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define PSHWPTE PX86PTEPAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHWPD X86PDPAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define PSHWPD PX86PDPAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHWPDE X86PDEPAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define PSHWPDE PX86PDEPAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PDE_PG_MASK X86_PDE_PAE_PG_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PD_SHIFT X86_PD_PAE_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PD_MASK X86_PD_PAE_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PTE_PG_MASK X86_PTE_PAE_PG_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PT_SHIFT X86_PT_PAE_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PT_MASK X86_PT_PAE_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if PGM_SHW_TYPE == PGM_TYPE_AMD64
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PDPTR_SHIFT X86_PDPTR_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PDPTR_MASK X86_PDPTR_MASK
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_PML4
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else /* 32 bits PAE mode */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PDPTR_SHIFT X86_PDPTR_SHIFT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_PDPTR_MASK X86_PDPTR_MASK_32
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_TOTAL_PD_ENTRIES (X86_PG_PAE_ENTRIES*X86_PG_PAE_PDPTE_ENTRIES)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_PAE_PD
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Internal Functions *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync__BEGIN_DECLS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_SHW_DECL(int, GetPage)(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_SHW_DECL(int, ModifyPage)(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_SHW_DECL(int, GetPDEByIndex)(PVM pVM, uint32_t iPD, PX86PDEPAE pPde);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_SHW_DECL(int, SetPDEByIndex)(PVM pVM, uint32_t iPD, X86PDEPAE Pde);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_SHW_DECL(int, ModifyPDEByIndex)(PVM pVM, uint32_t iPD, uint64_t fFlags, uint64_t fMask);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync__END_DECLS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Gets effective page information (from the VMM page directory).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM VM Handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param GCPtr Guest Context virtual address of the page.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pfFlags Where to store the flags. These are X86_PTE_*.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pHCPhys Where to store the HC physical address of the page.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This is page aligned.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @remark You should use PGMMapGetPage() for pages in a mapping.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_SHW_DECL(int, GetPage)(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get the PDE.
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if PGM_SHW_TYPE == PGM_TYPE_AMD64
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync /*
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync * For the first 4G we have preallocated page directories.
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync * Since the two upper levels contains only fixed flags, we skip those when possible.
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync */
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync X86PDEPAE Pde;
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync#if GC_ARCH_BITS == 64
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync if (GCPtr < _4G)
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPdptr = (GCPtr >> X86_PDPTR_SHIFT) & X86_PDPTR_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPd = (GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Pde = CTXMID(pVM->pgm.s.ap,PaePDs)[iPdptr]->a[iPd];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if GC_ARCH_BITS == 64
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* PML4 */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPml4 = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync X86PML4E Pml4e = CTXMID(pVM->pgm.s.p,PaePML4)->a[iPml4];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!Pml4e.n.u1Present)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_PAGE_TABLE_NOT_PRESENT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* PDPTR */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PX86PDPTR pPdPtr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = PGM_HCPHYS_2_PTR(pVM, Pml4e.u & X86_PML4E_PG_MASK, &pPdPtr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPdptr = (GCPtr >> X86_PDPTR_SHIFT) & X86_PDPTR_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync X86PDPE Pdpe = pPdPtr->a[iPdptr];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!Pdpe.n.u1Present)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_PAGE_TABLE_NOT_PRESENT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* PD */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PX86PDPAE pPd;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PGM_HCPHYS_2_PTR(pVM, Pdpe.u & X86_PDPE_PG_MASK, &pPd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPd = (GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Pdpe = pPdPtr->a[iPd];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* GC_ARCH_BITS == 64 */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync#elif PGM_SHW_TYPE == PGM_TYPE_PAE
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync const unsigned iPdptr = (GCPtr >> X86_PDPTR_SHIFT) & X86_PDPTR_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPd = (GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync X86PDEPAE Pde = CTXMID(pVM->pgm.s.ap,PaePDs)[iPdptr]->a[iPd];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else /* PGM_TYPE_32BIT */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPd = (GCPtr >> X86_PD_SHIFT) & X86_PD_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync X86PDE Pde = CTXMID(pVM->pgm.s.p,32BitPD)->a[iPd];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!Pde.n.u1Present)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_PAGE_TABLE_NOT_PRESENT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get PT entry.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PSHWPT pPT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!(Pde.u & PGM_PDFLAGS_MAPPING))
3ecf9412133496b2aeb090cfd33a286404ec59fbvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = PGM_HCPHYS_2_PTR(pVM, Pde.u & SHW_PDE_PG_MASK, &pPT);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else /* mapping: */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPGMMAPPING pMap = pgmGetMapping(pVM, (RTGCPTR)GCPtr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgReturn(pMap, ("GCPtr=%VGv\n", GCPtr), VERR_INTERNAL_ERROR);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if PGM_SHW_TYPE == PGM_TYPE_32BIT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPT = pMap->aPTs[(GCPtr - pMap->GCPtr) >> X86_PD_SHIFT].CTXALLSUFF(pPT);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else /* PAE and AMD64: */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPT = pMap->aPTs[(GCPtr - pMap->GCPtr) >> X86_PD_SHIFT].CTXALLSUFF(paPaePTs);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPt = (GCPtr >> SHW_PT_SHIFT) & SHW_PT_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync SHWPTE Pte = pPT->a[iPt];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!Pte.n.u1Present)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_PAGE_NOT_PRESENT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync * Store the results.
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * RW and US flags depend on the entire page transation hierarchy - except for
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * legacy PAE which has a simplified PDPE.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pfFlags)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pfFlags = (Pte.u & ~SHW_PTE_PG_MASK)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync & ((Pde.u & (X86_PTE_RW | X86_PTE_US)) | ~(uint64_t)(X86_PTE_RW | X86_PTE_US));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pHCPhys)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pHCPhys = Pte.u & SHW_PTE_PG_MASK;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync * Modify page flags for a range of pages in the shadow context.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The existing flags are ANDed with the fMask and ORed with the fFlags.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param GCPtr Virtual address of the first page in the range. Page aligned!
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param cb Size (in bytes) of the range to apply the modification to. Page aligned!
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param fFlags The OR mask - page flags X86_PTE_*, excluding the page mask of course.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param fMask The AND mask - page flags X86_PTE_*.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Be extremely CAREFUL with ~'ing values because they can be 32-bit!
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @remark You must use PGMMapModifyPage() for pages in a mapping.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_SHW_DECL(int, ModifyPage)(PVM pVM, RTGCUINTPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Walk page tables and pages till we're done.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (;;)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get the PDE.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if PGM_SHW_TYPE == PGM_TYPE_AMD64
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * For the first 4G we have preallocated page directories.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Since the two upper levels contains only fixed flags, we skip those when possible.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync X86PDEPAE Pde;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if GC_ARCH_BITS == 64
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (GCPtr < _4G)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPdptr = (GCPtr >> X86_PDPTR_SHIFT) & X86_PDPTR_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPd = (GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Pde = CTXMID(pVM->pgm.s.ap,PaePDs)[iPdptr]->a[iPd];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync#if GC_ARCH_BITS == 64
9782b553bdb12385214a3ac596aff1476bcb7cbdvboxsync else
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync {
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync /* PML4 */
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync const unsigned iPml4 = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync X86PML4E Pml4e = CTXMID(pVM->pgm.s.p,PaePML4)->a[iPml4];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!Pml4e.n.u1Present)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_PAGE_TABLE_NOT_PRESENT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* PDPTR */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PX86PDPTR pPdPtr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = PGM_HCPHYS_2_PTR(pVM, Pml4e.u & X86_PML4E_PG_MASK, &pPdPtr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync const unsigned iPdptr = (GCPtr >> X86_PDPTR_SHIFT) & X86_PDPTR_MASK;
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync X86PDPE Pdpe = pPdPtr->a[iPdptr];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!Pdpe.n.u1Present)
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync return VERR_PAGE_TABLE_NOT_PRESENT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* PD */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PX86PDPAE pPd;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PGM_HCPHYS_2_PTR(pVM, Pdpe.u & X86_PDPE_PG_MASK, &pPd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPd = (GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Pdpe = pPdPtr->a[iPd];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* GC_ARCH_BITS == 64 */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#elif PGM_SHW_TYPE == PGM_TYPE_PAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPdptr = (GCPtr >> X86_PDPTR_SHIFT) & X86_PDPTR_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPd = (GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync X86PDEPAE Pde = CTXMID(pVM->pgm.s.ap,PaePDs)[iPdptr]->a[iPd];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else /* PGM_TYPE_32BIT */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned iPd = (GCPtr >> X86_PD_SHIFT) & X86_PD_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync X86PDE Pde = CTXMID(pVM->pgm.s.p,32BitPD)->a[iPd];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!Pde.n.u1Present)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_PAGE_TABLE_NOT_PRESENT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Map the page table.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PSHWPT pPT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = PGM_HCPHYS_2_PTR(pVM, Pde.u & SHW_PDE_PG_MASK, &pPT);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBOX_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unsigned iPTE = (GCPtr >> SHW_PT_SHIFT) & SHW_PT_MASK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (iPTE < ELEMENTS(pPT->a))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pPT->a[iPTE].n.u1Present)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPT->a[iPTE].u = (pPT->a[iPTE].u & (fMask | SHW_PTE_PG_MASK)) | (fFlags & ~SHW_PTE_PG_MASK);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pPT->a[iPTE].n.u1Present);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PGM_INVL_PG(GCPtr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
e52f819639386db020b2a635b47a415248c7fbf9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* next page */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cb -= PAGE_SIZE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!cb)
e02db9e0d46f862430895b82b10e8ecde075cf11vboxsync return VINF_SUCCESS;
680ca45722ec7123029ced4f88dfad87b397ef52vboxsync GCPtr += PAGE_SIZE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync iPTE++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
0e77737b0ba913683e614db11463b31ca67aacbevboxsync * Retrieve shadow PDE
0e77737b0ba913683e614db11463b31ca67aacbevboxsync *
0e77737b0ba913683e614db11463b31ca67aacbevboxsync * @returns VBox status code.
0e77737b0ba913683e614db11463b31ca67aacbevboxsync * @param pVM The virtual machine.
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync * @param iPD Shadow PDE index.
0e77737b0ba913683e614db11463b31ca67aacbevboxsync * @param pPde Where to store the shadow PDE entry.
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync */
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsyncPGM_SHW_DECL(int, GetPDEByIndex)(PVM pVM, unsigned iPD, PX86PDEPAE pPde)
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync{
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync#if PGM_SHW_TYPE == PGM_TYPE_32BIT || PGM_SHW_TYPE == PGM_TYPE_PAE
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync /*
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync * Get page directory addresses.
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync */
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync Assert(iPD < SHW_TOTAL_PD_ENTRIES);
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync# if PGM_SHW_TYPE == PGM_TYPE_32BIT
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync PX86PDE pPdeSrc = &CTXMID(pVM->pgm.s.p,32BitPD)->a[iPD];
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync# else
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync PX86PDEPAE pPdeSrc = &CTXMID(pVM->pgm.s.ap,PaePDs)[0]->a[iPD]; /* We treat this as a PD with 2048 entries. */
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync# endif
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync
0e77737b0ba913683e614db11463b31ca67aacbevboxsync pPde->u = (X86PGPAEUINT)pPdeSrc->u;
0e77737b0ba913683e614db11463b31ca67aacbevboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertFailed();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_NOT_IMPLEMENTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * Set shadow PDE
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM The virtual machine.
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync * @param iPD Shadow PDE index.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param Pde Shadow PDE.
e98b0df488a9ec7732b1d5c2e735ce707842e975vboxsync */
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsyncPGM_SHW_DECL(int, SetPDEByIndex)(PVM pVM, unsigned iPD, X86PDEPAE Pde)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync#if PGM_SHW_TYPE == PGM_TYPE_32BIT || PGM_SHW_TYPE == PGM_TYPE_PAE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get page directory addresses and update the specified entry.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(iPD < SHW_TOTAL_PD_ENTRIES);
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync# if PGM_SHW_TYPE == PGM_TYPE_32BIT
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync Assert(Pde.au32[1] == 0); /* First uint32_t is backwards compatible. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Pde.n.u1Size == 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PX86PDE pPdeDst = &CTXMID(pVM->pgm.s.p,32BitPD)->a[iPD];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPdeDst->u = Pde.au32[0];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PX86PDEPAE pPdeDst = &CTXMID(pVM->pgm.s.ap,PaePDs)[0]->a[iPD]; /* We treat this as a PD with 2048 entries. */
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync pPdeDst->u = Pde.u;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pPdeDst->n.u1Present);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync AssertFailed();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_NOT_IMPLEMENTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Modify shadow PDE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync * @param pVM The virtual machine.
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync * @param iPD Shadow PDE index.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param fFlags The OR mask - page flags X86_PDE_*, excluding the page mask of course.
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync * @param fMask The AND mask - page flags X86_PDE_*.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Be extremely CAREFUL with ~'ing values because they can be 32-bit!
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync */
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsyncPGM_SHW_DECL(int, ModifyPDEByIndex)(PVM pVM, uint32_t iPD, uint64_t fFlags, uint64_t fMask)
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync{
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync#if PGM_SHW_TYPE == PGM_TYPE_32BIT || PGM_SHW_TYPE == PGM_TYPE_PAE
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync /*
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync * Get page directory addresses and update the specified entry.
a6936eab59adc5624216e6e5e5e455fc6a40df7fvboxsync */
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync Assert(iPD < SHW_TOTAL_PD_ENTRIES);
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync# if PGM_SHW_TYPE == PGM_TYPE_32BIT
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync PX86PDE pPdeDst = &CTXMID(pVM->pgm.s.p,32BitPD)->a[iPD];
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync pPdeDst->u = ((pPdeDst->u & ((X86PGUINT)fMask | SHW_PDE_PG_MASK)) | ((X86PGUINT)fFlags & ~SHW_PDE_PG_MASK));
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync Assert(!pPdeDst->n.u1Size);
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync# else
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync PX86PDEPAE pPdeDst = &CTXMID(pVM->pgm.s.ap,PaePDs)[0]->a[iPD]; /* We treat this as a PD with 2048 entries. */
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync pPdeDst->u = (pPdeDst->u & (fMask | SHW_PDE_PG_MASK)) | (fFlags & ~SHW_PDE_PG_MASK);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pPdeDst->n.u1Present);
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync return VINF_SUCCESS;
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync#else
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync AssertFailed();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_NOT_IMPLEMENTED;
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync