PGMAllMap.cpp revision 2582b184d9f48e3338b21a04df9b24adc869f22b
c74832c7184337c330041742d88e6dacaa07b378vboxsync/* $Id$ */
c74832c7184337c330041742d88e6dacaa07b378vboxsync/** @file
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * PGM - Page Manager and Monitor - All context code.
d192cc72774b02a0df2fdd46350d418236ac09aevboxsync */
d192cc72774b02a0df2fdd46350d418236ac09aevboxsync
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync/*
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
c74832c7184337c330041742d88e6dacaa07b378vboxsync *
c74832c7184337c330041742d88e6dacaa07b378vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * available from http://www.virtualbox.org. This file is free software;
c74832c7184337c330041742d88e6dacaa07b378vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c74832c7184337c330041742d88e6dacaa07b378vboxsync * General Public License (GPL) as published by the Free Software
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c74832c7184337c330041742d88e6dacaa07b378vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
c74832c7184337c330041742d88e6dacaa07b378vboxsync * additional information or have any questions.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync/*******************************************************************************
c74832c7184337c330041742d88e6dacaa07b378vboxsync* Header Files *
c74832c7184337c330041742d88e6dacaa07b378vboxsync*******************************************************************************/
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#define LOG_GROUP LOG_GROUP_PGM
c74832c7184337c330041742d88e6dacaa07b378vboxsync#include <VBox/pgm.h>
c74832c7184337c330041742d88e6dacaa07b378vboxsync#include "PGMInternal.h"
c74832c7184337c330041742d88e6dacaa07b378vboxsync#include <VBox/vm.h>
c74832c7184337c330041742d88e6dacaa07b378vboxsync#include <iprt/assert.h>
c74832c7184337c330041742d88e6dacaa07b378vboxsync#include <iprt/asm.h>
c74832c7184337c330041742d88e6dacaa07b378vboxsync#include <VBox/err.h>
f5e53763b0a581b0299e98028c6c52192eb06785vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync/**
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * Maps a range of physical pages at a given virtual address
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * in the guest context.
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync *
c74832c7184337c330041742d88e6dacaa07b378vboxsync * The GC virtual address range must be within an existing mapping.
c74832c7184337c330041742d88e6dacaa07b378vboxsync *
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @returns VBox status code.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pVM The virtual machine.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param GCPtr Where to map the page(s). Must be page aligned.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param HCPhys Start of the range of physical pages. Must be page aligned.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param cbPages Number of bytes to map. Must be page aligned.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param fFlags Page flags (X86_PTE_*).
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsyncVMMDECL(int) PGMMap(PVM pVM, RTGCUINTPTR GCPtr, RTHCPHYS HCPhys, uint32_t cbPages, unsigned fFlags)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync{
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertMsg(pVM->pgm.s.offVM, ("Bad init order\n"));
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Validate input.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertMsg(RT_ALIGN_T(GCPtr, PAGE_SIZE, RTGCUINTPTR) == GCPtr, ("Invalid alignment GCPtr=%#x\n", GCPtr));
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertMsg(cbPages > 0 && RT_ALIGN_32(cbPages, PAGE_SIZE) == cbPages, ("Invalid cbPages=%#x\n", cbPages));
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertMsg(!(fFlags & X86_PDE_PG_MASK), ("Invalid flags %#x\n", fFlags));
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /* hypervisor defaults */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (!fFlags)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync fFlags = X86_PTE_P | X86_PTE_A | X86_PTE_D;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /*
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Find the mapping.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync while (pCur)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (GCPtr - pCur->GCPtr < pCur->cb)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (GCPtr + cbPages - 1 > pCur->GCPtrLast)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertMsgFailed(("Invalid range!!\n"));
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return VERR_INVALID_PARAMETER;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /*
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Setup PTE.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync X86PTEPAE Pte;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync Pte.u = fFlags | (HCPhys & X86_PTE_PAE_PG_MASK);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /*
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Update the page tables.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync for (;;)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync RTGCUINTPTR off = GCPtr - pCur->GCPtr;
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync const unsigned iPT = off >> X86_PD_SHIFT;
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync const unsigned iPageNo = (off >> PAGE_SHIFT) & X86_PT_MASK;
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync /* 32-bit */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync 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! */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync /* pae */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync pCur->aPTs[iPT].CTX_SUFF(paPaePTs)[iPageNo / 512].a[iPageNo % 512].u = Pte.u;
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /* next */
c74832c7184337c330041742d88e6dacaa07b378vboxsync cbPages -= PAGE_SIZE;
c74832c7184337c330041742d88e6dacaa07b378vboxsync if (!cbPages)
c74832c7184337c330041742d88e6dacaa07b378vboxsync break;
c74832c7184337c330041742d88e6dacaa07b378vboxsync GCPtr += PAGE_SIZE;
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync Pte.u += PAGE_SIZE;
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync }
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync return VINF_SUCCESS;
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync }
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync /* next */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync pCur = pCur->CTX_SUFF(pNext);
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync }
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync AssertMsgFailed(("GCPtr=%#x was not found in any mapping ranges!\n", GCPtr));
c74832c7184337c330041742d88e6dacaa07b378vboxsync return VERR_INVALID_PARAMETER;
0c34933fc8f84dd5183d1897881bbc7683d24541vboxsync}
c74832c7184337c330041742d88e6dacaa07b378vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync/**
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * Sets (replaces) the page flags for a range of pages in a mapping.
c74832c7184337c330041742d88e6dacaa07b378vboxsync *
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @returns VBox status.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pVM VM handle.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param GCPtr Virtual address of the first page in the range.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param cb Size (in bytes) of the range to apply the modification to.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param fFlags Page flags X86_PTE_*, excluding the page mask of course.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncVMMDECL(int) PGMMapSetPage(PVM pVM, RTGCPTR GCPtr, uint64_t cb, uint64_t fFlags)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync{
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return PGMMapModifyPage(pVM, GCPtr, cb, fFlags, 0);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync}
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync/**
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Modify page flags for a range of pages in a mapping.
c74832c7184337c330041742d88e6dacaa07b378vboxsync *
c74832c7184337c330041742d88e6dacaa07b378vboxsync * The existing flags are ANDed with the fMask and ORed with the fFlags.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync *
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @returns VBox status code.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pVM VM handle.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param GCPtr Virtual address of the first page in the range.
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * @param cb Size (in bytes) of the range to apply the modification to.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param fFlags The OR mask - page flags X86_PTE_*, excluding the page mask of course.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param fMask The AND mask - page flags X86_PTE_*, excluding the page mask of course.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsyncVMMDECL(int) PGMMapModifyPage(PVM pVM, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask)
c74832c7184337c330041742d88e6dacaa07b378vboxsync{
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Validate input.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync AssertMsg(!(fFlags & X86_PTE_PAE_PG_MASK), ("fFlags=%#x\n", fFlags));
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(cb);
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * Align the input.
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync */
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync cb += (RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK;
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync cb = RT_ALIGN_Z(cb, PAGE_SIZE);
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync GCPtr = (RTGCPTR)((RTGCUINTPTR)GCPtr & PAGE_BASE_GC_MASK);
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Find the mapping.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync while (pCur)
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync RTGCUINTPTR off = (RTGCUINTPTR)GCPtr - (RTGCUINTPTR)pCur->GCPtr;
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync if (off < pCur->cb)
509c0d9c2c05b40f3f07f79e44c06c9395c1b293vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertMsgReturn(off + cb <= pCur->cb,
c74832c7184337c330041742d88e6dacaa07b378vboxsync ("Invalid page range %#x LB%#x. mapping '%s' %#x to %#x\n",
4fbca3751fe239da5934c23a783c3422618336e8vboxsync GCPtr, cb, pCur->pszDesc, pCur->GCPtr, pCur->GCPtrLast),
4fbca3751fe239da5934c23a783c3422618336e8vboxsync VERR_INVALID_PARAMETER);
c74832c7184337c330041742d88e6dacaa07b378vboxsync
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync /*
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Perform the requested operation.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsync while (cb > 0)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync unsigned iPT = off >> X86_PD_SHIFT;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync unsigned iPTE = (off >> PAGE_SHIFT) & X86_PT_MASK;
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync while (cb > 0 && iPTE < RT_ELEMENTS(pCur->aPTs[iPT].CTX_SUFF(pPT)->a))
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
509c0d9c2c05b40f3f07f79e44c06c9395c1b293vboxsync /* 32-Bit */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pCur->aPTs[iPT].CTX_SUFF(pPT)->a[iPTE].u &= fMask | X86_PTE_PG_MASK;
c74832c7184337c330041742d88e6dacaa07b378vboxsync pCur->aPTs[iPT].CTX_SUFF(pPT)->a[iPTE].u |= fFlags & ~X86_PTE_PG_MASK;
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /* PAE */
c74832c7184337c330041742d88e6dacaa07b378vboxsync pCur->aPTs[iPT].CTX_SUFF(paPaePTs)[iPTE / 512].a[iPTE % 512].u &= fMask | X86_PTE_PAE_PG_MASK;
c74832c7184337c330041742d88e6dacaa07b378vboxsync pCur->aPTs[iPT].CTX_SUFF(paPaePTs)[iPTE / 512].a[iPTE % 512].u |= fFlags & ~X86_PTE_PAE_PG_MASK;
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /* invalidate tls */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PGM_INVL_PG((RTGCUINTPTR)pCur->GCPtr + off);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /* next */
c74832c7184337c330041742d88e6dacaa07b378vboxsync iPTE++;
c74832c7184337c330041742d88e6dacaa07b378vboxsync cb -= PAGE_SIZE;
c74832c7184337c330041742d88e6dacaa07b378vboxsync off += PAGE_SIZE;
c74832c7184337c330041742d88e6dacaa07b378vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync return VINF_SUCCESS;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync /* next */
c74832c7184337c330041742d88e6dacaa07b378vboxsync pCur = pCur->CTX_SUFF(pNext);
c74832c7184337c330041742d88e6dacaa07b378vboxsync }
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertMsgFailed(("Page range %#x LB%#x not found\n", GCPtr, cb));
c74832c7184337c330041742d88e6dacaa07b378vboxsync return VERR_INVALID_PARAMETER;
c74832c7184337c330041742d88e6dacaa07b378vboxsync}
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync#ifndef IN_RING0
c74832c7184337c330041742d88e6dacaa07b378vboxsync/**
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync * Sets all PDEs involved with the mapping in the shadow page table.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync *
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pVM The VM handle.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pMap Pointer to the mapping in question.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param iNewPDE The index of the 32-bit PDE corresponding to the base of the mapping.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncvoid pgmMapSetShadowPDEs(PVM pVM, PPGMMAPPING pMap, unsigned iNewPDE)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync{
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (!pgmMapAreMappingsEnabled(&pVM->pgm.s))
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
c74832c7184337c330041742d88e6dacaa07b378vboxsync if (!pVM->pgm.s.CTX_SUFF(pShwPageCR3))
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return; /* too early */
c74832c7184337c330041742d88e6dacaa07b378vboxsync#endif
c74832c7184337c330041742d88e6dacaa07b378vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PGMMODE enmShadowMode = PGMGetShadowMode(pVM);
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(enmShadowMode <= PGMMODE_PAE_NX);
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Init the page tables and insert them into the page directories.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsync unsigned i = pMap->cPTs;
c74832c7184337c330041742d88e6dacaa07b378vboxsync iNewPDE += i;
c74832c7184337c330041742d88e6dacaa07b378vboxsync while (i-- > 0)
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync iNewPDE--;
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync switch(enmShadowMode)
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync case PGMMODE_32_BIT:
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync PX86PD pShw32BitPd = pgmShwGet32BitPDPtr(&pVM->pgm.s);
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertFatal(pShw32BitPd);
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync if (pShw32BitPd->a[iNewPDE].n.u1Present)
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(!(pShw32BitPd->a[iNewPDE].u & PGM_PDFLAGS_MAPPING));
c74832c7184337c330041742d88e6dacaa07b378vboxsync pgmPoolFree(pVM, pShw32BitPd->a[iNewPDE].u & X86_PDE_PG_MASK, pVM->pgm.s.CTX_SUFF(pShwPageCR3)->idx, iNewPDE);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync X86PDE Pde;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /* Default mapping page directory flags are read/write and supervisor; individual page attributes determine the final flags */
c74832c7184337c330041742d88e6dacaa07b378vboxsync Pde.u = PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPT;
c74832c7184337c330041742d88e6dacaa07b378vboxsync pShw32BitPd->a[iNewPDE] = Pde;
c74832c7184337c330041742d88e6dacaa07b378vboxsync break;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync case PGMMODE_PAE:
4fbca3751fe239da5934c23a783c3422618336e8vboxsync case PGMMODE_PAE_NX:
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync PX86PDPT pShwPdpt;
c74832c7184337c330041742d88e6dacaa07b378vboxsync PX86PDPAE pShwPaePd;
c74832c7184337c330041742d88e6dacaa07b378vboxsync const unsigned iPdPt = iNewPDE / 256;
c74832c7184337c330041742d88e6dacaa07b378vboxsync unsigned iPDE = iNewPDE * 2 % 512;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync pShwPdpt = pgmShwGetPaePDPTPtr(&pVM->pgm.s);
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(pShwPdpt);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, (iPdPt << X86_PDPT_SHIFT));
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (!pShwPaePd)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync X86PDPE GstPdpe;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (PGMGetGuestMode(pVM) < PGMMODE_PAE)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync /* Fake PDPT entry; access control handled on the page table level, so allow everything. */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync GstPdpe.u = X86_PDPE_P; /* rw/us are reserved for PAE pdpte's; accessed bit causes invalid VT-x guest state errors */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync else
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync PX86PDPE pGstPdpe;
c74832c7184337c330041742d88e6dacaa07b378vboxsync pGstPdpe = pgmGstGetPaePDPEPtr(&pVM->pgm.s, (iPdPt << X86_PDPT_SHIFT));
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertFatal(pGstPdpe);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync GstPdpe = *pGstPdpe;
c74832c7184337c330041742d88e6dacaa07b378vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync int rc = pgmShwSyncPaePDPtr(pVM, (iPdPt << X86_PDPT_SHIFT), &GstPdpe, &pShwPaePd);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertFatal(RT_SUCCESS(rc));
c74832c7184337c330041742d88e6dacaa07b378vboxsync if (rc != VINF_SUCCESS)
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync rc = pgmShwSyncPaePDPtr(pVM, (iPdPt << X86_PDPT_SHIFT), &GstPdpe, &pShwPaePd);
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertFatalMsg(rc == VINF_SUCCESS, ("rc = %Rrc\n", rc));
c74832c7184337c330041742d88e6dacaa07b378vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync#endif
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertFatal(pShwPaePd);
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync PPGMPOOLPAGE pPoolPagePde = pgmPoolGetPageByHCPhys(pVM, pShwPdpt->a[iPdPt].u & X86_PDPE_PG_MASK);
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertFatal(pPoolPagePde);
c74832c7184337c330041742d88e6dacaa07b378vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (pShwPaePd->a[iPDE].n.u1Present)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(!(pShwPaePd->a[iPDE].u & PGM_PDFLAGS_MAPPING));
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pgmPoolFree(pVM, pShwPaePd->a[iPDE].u & X86_PDE_PG_MASK, pPoolPagePde->idx, iNewPDE);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync X86PDEPAE PdePae0;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PdePae0.u = PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT0;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pShwPaePd->a[iPDE] = PdePae0;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /* 2nd 2 MB PDE of the 4 MB region */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync iPDE++;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertFatal(iPDE < 512);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (pShwPaePd->a[iPDE].n.u1Present)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync Assert(!(pShwPaePd->a[iPDE].u & PGM_PDFLAGS_MAPPING));
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pgmPoolFree(pVM, pShwPaePd->a[iPDE].u & X86_PDE_PG_MASK, pPoolPagePde->idx, iNewPDE);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync X86PDEPAE PdePae1;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PdePae1.u = PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT1;
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync pShwPaePd->a[iPDE] = PdePae1;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /* Set the PGM_PDFLAGS_MAPPING flag in the page directory pointer entry. (legacy PAE guest mode) */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pShwPdpt->a[iPdPt].u |= PGM_PLXFLAGS_MAPPING;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync break;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync default:
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertFailed();
4fbca3751fe239da5934c23a783c3422618336e8vboxsync break;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync}
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync/**
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Clears all PDEs involved with the mapping in the shadow page table.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync *
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync * @param pVM The VM handle.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pShwPageCR3 CR3 root page
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync * @param pMap Pointer to the mapping in question.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param iOldPDE The index of the 32-bit PDE corresponding to the base of the mapping.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsyncvoid pgmMapClearShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iOldPDE)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync{
4fbca3751fe239da5934c23a783c3422618336e8vboxsync Assert(pShwPageCR3);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (!pgmMapAreMappingsEnabled(&pVM->pgm.s))
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (!pVM->pgm.s.CTX_SUFF(pShwPageCR3))
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return; /* too early */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#endif
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync unsigned i = pMap->cPTs;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PGMMODE enmShadowMode = PGMGetShadowMode(pVM);
c74832c7184337c330041742d88e6dacaa07b378vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync iOldPDE += i;
c74832c7184337c330041742d88e6dacaa07b378vboxsync while (i-- > 0)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync iOldPDE--;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync switch(enmShadowMode)
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync case PGMMODE_32_BIT:
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PX86PD pShw32BitPd = (PX86PD)PGMPOOL_PAGE_2_PTR_BY_PGM(&pVM->pgm.s, pShwPageCR3);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#else
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PX86PD pShw32BitPd = pgmShwGet32BitPDPtr(&pVM->pgm.s);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#endif
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertFatal(pShw32BitPd);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pShw32BitPd->a[iOldPDE].u = 0;
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync break;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync case PGMMODE_PAE:
4fbca3751fe239da5934c23a783c3422618336e8vboxsync case PGMMODE_PAE_NX:
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PX86PDPT pPdpt = NULL;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PX86PDPAE pShwPaePd = NULL;
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync const unsigned iPD = iOldPDE / 256; /* iOldPDE * 2 / 512; iOldPDE is in 4 MB pages */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync unsigned iPDE = iOldPDE * 2 % 512;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pPdpt = (PX86PDPT)PGMPOOL_PAGE_2_PTR_BY_PGM(&pVM->pgm.s, pShwPageCR3);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, pPdpt, (iPD << X86_PDPT_SHIFT));
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#else
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pPdpt = pgmShwGetPaePDPTPtr(&pVM->pgm.s);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, (iPD << X86_PDPT_SHIFT));
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#endif
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertFatal(pShwPaePd);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pShwPaePd->a[iPDE].u = 0;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync iPDE++;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertFatal(iPDE < 512);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pShwPaePd->a[iPDE].u = 0;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /* Clear the PGM_PDFLAGS_MAPPING flag for the page directory pointer entry. (legacy PAE guest mode) */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pPdpt->a[iPD].u &= ~PGM_PLXFLAGS_MAPPING;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync break;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync default:
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertFailed();
4fbca3751fe239da5934c23a783c3422618336e8vboxsync break;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
4fbca3751fe239da5934c23a783c3422618336e8vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync}
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#endif /* !IN_RING0 */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync/**
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Apply the hypervisor mappings to the active CR3.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync *
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @returns VBox status.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @param pVM The virtual machine.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsyncVMMDECL(int) PGMMapActivateAll(PVM pVM)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync{
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Can skip this if mappings are safely fixed.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsync if (pVM->pgm.s.fMappingsFixed)
c74832c7184337c330041742d88e6dacaa07b378vboxsync return VINF_SUCCESS;
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync#ifdef IN_RING0
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertFailed();
c74832c7184337c330041742d88e6dacaa07b378vboxsync return VERR_INTERNAL_ERROR;
c74832c7184337c330041742d88e6dacaa07b378vboxsync#else
c74832c7184337c330041742d88e6dacaa07b378vboxsync# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(pVM->pgm.s.CTX_SUFF(pShwPageCR3));
c74832c7184337c330041742d88e6dacaa07b378vboxsync# endif
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Iterate mappings.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; pCur = pCur->CTX_SUFF(pNext))
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync unsigned iPDE = pCur->GCPtr >> X86_PD_SHIFT;
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync pgmMapSetShadowPDEs(pVM, pCur, iPDE);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync }
c74832c7184337c330041742d88e6dacaa07b378vboxsync return VINF_SUCCESS;
c74832c7184337c330041742d88e6dacaa07b378vboxsync#endif /* IN_RING0 */
c74832c7184337c330041742d88e6dacaa07b378vboxsync}
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync/**
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Remove the hypervisor mappings from the active CR3
c74832c7184337c330041742d88e6dacaa07b378vboxsync *
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @returns VBox status.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pVM The virtual machine.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsyncVMMDECL(int) PGMMapDeactivateAll(PVM pVM)
c74832c7184337c330041742d88e6dacaa07b378vboxsync{
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Can skip this if mappings are safely fixed.
c74832c7184337c330041742d88e6dacaa07b378vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsync if (pVM->pgm.s.fMappingsFixed)
c74832c7184337c330041742d88e6dacaa07b378vboxsync return VINF_SUCCESS;
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync#ifdef IN_RING0
c74832c7184337c330041742d88e6dacaa07b378vboxsync AssertFailed();
c74832c7184337c330041742d88e6dacaa07b378vboxsync return VERR_INTERNAL_ERROR;
d59a43b735abea2db17caa9b5661d2f5118f0e02vboxsync#else
c74832c7184337c330041742d88e6dacaa07b378vboxsync# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(pVM->pgm.s.CTX_SUFF(pShwPageCR3));
c74832c7184337c330041742d88e6dacaa07b378vboxsync# endif
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync /*
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Iterate mappings.
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync */
c74832c7184337c330041742d88e6dacaa07b378vboxsync for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; pCur = pCur->CTX_SUFF(pNext))
c74832c7184337c330041742d88e6dacaa07b378vboxsync {
c74832c7184337c330041742d88e6dacaa07b378vboxsync unsigned iPDE = pCur->GCPtr >> X86_PD_SHIFT;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync pgmMapClearShadowPDEs(pVM, pVM->pgm.s.CTX_SUFF(pShwPageCR3), pCur, iPDE);
c74832c7184337c330041742d88e6dacaa07b378vboxsync }
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return VINF_SUCCESS;
c74832c7184337c330041742d88e6dacaa07b378vboxsync#endif /* IN_RING0 */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync}
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync
c74832c7184337c330041742d88e6dacaa07b378vboxsync/**
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Remove the hypervisor mappings from the specified CR3
c74832c7184337c330041742d88e6dacaa07b378vboxsync *
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @returns VBox status.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pVM The virtual machine.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pShwPageCR3 CR3 root page
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncint pgmMapDeactivateCR3(PVM pVM, PPGMPOOLPAGE pShwPageCR3)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync{
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /*
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Can skip this if mappings are safely fixed.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync if (pVM->pgm.s.fMappingsFixed)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return VINF_SUCCESS;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#ifdef IN_RING0
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertFailed();
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return VERR_INTERNAL_ERROR;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#else
4fbca3751fe239da5934c23a783c3422618336e8vboxsync# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
4fbca3751fe239da5934c23a783c3422618336e8vboxsync Assert(pVM->pgm.s.CTX_SUFF(pShwPageCR3));
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync# endif
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync
4fbca3751fe239da5934c23a783c3422618336e8vboxsync /*
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Iterate mappings.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; pCur = pCur->CTX_SUFF(pNext))
4fbca3751fe239da5934c23a783c3422618336e8vboxsync {
4fbca3751fe239da5934c23a783c3422618336e8vboxsync unsigned iPDE = pCur->GCPtr >> X86_PD_SHIFT;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync pgmMapClearShadowPDEs(pVM, pShwPageCR3, pCur, iPDE);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync }
4fbca3751fe239da5934c23a783c3422618336e8vboxsync return VINF_SUCCESS;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync#endif /* IN_RING0 */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync}
4fbca3751fe239da5934c23a783c3422618336e8vboxsync