PGMR0.cpp revision 28d7c24dda3ad9c1c47a3f77454193b1a48da852
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * PGM - Page Manager and Monitor, Ring-0.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync * Copyright (C) 2007 Sun Microsystems, Inc.
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.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * additional information or have any questions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Header Files *
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync*******************************************************************************/
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/pgm.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include "PGMInternal.h"
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vm.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/log.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/err.h>
f091ce66ee934d599f16056078a9a76d7286b959vboxsync#include <iprt/assert.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync__BEGIN_DECLS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_32BIT_PROT(name)
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include "PGMR0Bth.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef PGM_BTH_NAME
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_PAE_PROT(name)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "PGMR0Bth.h"
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync#undef PGM_BTH_NAME
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync#define PGM_BTH_NAME(name) PGM_BTH_NAME_AMD64_PROT(name)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "PGMR0Bth.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef PGM_BTH_NAME
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync__END_DECLS
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Worker function for PGMR3PhysAllocateHandyPages and pgmPhysEnsureHandyPage.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns The following VBox status codes.
ffa39e5fea478b00909918ab8d45fb3ffb02bc14vboxsync * @retval VINF_SUCCESS on success. FF cleared.
11923fc977be1686f5428c3e790c04d0701a074cvboxsync * @retval VINF_EM_NO_MEMORY if we're out of memory. The FF is set in this case.
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync *
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync * @param pVM The VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @remarks Must be called from within the PGM critical section.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync return VERR_NOT_IMPLEMENTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync/**
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * #PF Handler for nested paging.
ffa39e5fea478b00909918ab8d45fb3ffb02bc14vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code (appropriate for trap handling and GC return).
953292a637f7ecfbb7340914e718919c84464f54vboxsync * @param pVM VM Handle.
953292a637f7ecfbb7340914e718919c84464f54vboxsync * @param enmShwPagingMode Paging mode for the nested page tables
953292a637f7ecfbb7340914e718919c84464f54vboxsync * @param uErr The trap error code.
953292a637f7ecfbb7340914e718919c84464f54vboxsync * @param pRegFrame Trap register frame.
953292a637f7ecfbb7340914e718919c84464f54vboxsync * @param pvFault The fault address.
b14c09e8af60e4d1ba4da27da03cbd175617f298vboxsync */
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsyncPGMR0DECL(int) PGMR0Trap0eHandlerNestedPaging(PVM pVM, PGMMODE enmShwPagingMode, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPHYS pvFault)
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync{
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync int rc;
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync LogFlow(("PGMTrap0eHandler: uErr=%#x pvFault=%VGp eip=%VGv\n", uErr, pvFault, pRegFrame->rip));
953292a637f7ecfbb7340914e718919c84464f54vboxsync STAM_PROFILE_START(&pVM->pgm.s.StatGCTrap0e, a);
953292a637f7ecfbb7340914e718919c84464f54vboxsync STAM_STATS({ pVM->pgm.s.CTXSUFF(pStatTrap0eAttribution) = NULL; } );
953292a637f7ecfbb7340914e718919c84464f54vboxsync
de81f2eda29daedff996cca9c60b29e899f17ff6vboxsync /* AMD uses the host's paging mode; Intel's version is on the todo list */
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync AssertMsg(enmShwPagingMode == PGMMODE_32_BIT || enmShwPagingMode == PGMMODE_PAE || enmShwPagingMode == PGMMODE_PAE_NX || enmShwPagingMode == PGMMODE_AMD64 || enmShwPagingMode == PGMMODE_AMD64_NX, ("enmShwPagingMode=%d\n", enmShwPagingMode));
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync
953292a637f7ecfbb7340914e718919c84464f54vboxsync#ifdef VBOX_WITH_STATISTICS
b14c09e8af60e4d1ba4da27da03cbd175617f298vboxsync /*
953292a637f7ecfbb7340914e718919c84464f54vboxsync * Error code stats.
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync */
953292a637f7ecfbb7340914e718919c84464f54vboxsync if (uErr & X86_TRAP_PF_US)
953292a637f7ecfbb7340914e718919c84464f54vboxsync {
953292a637f7ecfbb7340914e718919c84464f54vboxsync if (!(uErr & X86_TRAP_PF_P))
953292a637f7ecfbb7340914e718919c84464f54vboxsync {
953292a637f7ecfbb7340914e718919c84464f54vboxsync if (uErr & X86_TRAP_PF_RW)
953292a637f7ecfbb7340914e718919c84464f54vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eUSNotPresentWrite);
953292a637f7ecfbb7340914e718919c84464f54vboxsync else
953292a637f7ecfbb7340914e718919c84464f54vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eUSNotPresentRead);
b14c09e8af60e4d1ba4da27da03cbd175617f298vboxsync }
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync else if (uErr & X86_TRAP_PF_RW)
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eUSWrite);
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync else if (uErr & X86_TRAP_PF_RSVD)
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eUSReserved);
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync else if (uErr & X86_TRAP_PF_ID)
953292a637f7ecfbb7340914e718919c84464f54vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eUSNXE);
953292a637f7ecfbb7340914e718919c84464f54vboxsync else
953292a637f7ecfbb7340914e718919c84464f54vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eUSRead);
de81f2eda29daedff996cca9c60b29e899f17ff6vboxsync }
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync else
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync { /* Supervisor */
953292a637f7ecfbb7340914e718919c84464f54vboxsync if (!(uErr & X86_TRAP_PF_P))
b14c09e8af60e4d1ba4da27da03cbd175617f298vboxsync {
953292a637f7ecfbb7340914e718919c84464f54vboxsync if (uErr & X86_TRAP_PF_RW)
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eSVNotPresentWrite);
953292a637f7ecfbb7340914e718919c84464f54vboxsync else
953292a637f7ecfbb7340914e718919c84464f54vboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eSVNotPresentRead);
953292a637f7ecfbb7340914e718919c84464f54vboxsync }
ce666b71b4eb6477625b0057689a08aaa7c11b64vboxsync else if (uErr & X86_TRAP_PF_RW)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eSVWrite);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if (uErr & X86_TRAP_PF_ID)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eSNXE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if (uErr & X86_TRAP_PF_RSVD)
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync STAM_COUNTER_INC(&pVM->pgm.s.StatGCTrap0eSVReserved);
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync }
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync#endif
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync /*
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * Call the worker.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync *
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * We pretend the guest is in protected mode without paging, so we can use existing code to build the
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * nested page tables.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync */
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync switch(enmShwPagingMode)
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync {
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync case PGMMODE_32_BIT:
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync rc = PGM_BTH_NAME_32BIT_PROT(Trap0eHandler)(pVM, uErr, pRegFrame, pvFault);
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync break;
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync case PGMMODE_PAE:
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync rc = PGM_BTH_NAME_PAE_PROT(Trap0eHandler)(pVM, uErr, pRegFrame, pvFault);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case PGMMODE_AMD64:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PGM_BTH_NAME_AMD64_PROT(Trap0eHandler)(pVM, uErr, pRegFrame, pvFault);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync }
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync if (rc == VINF_PGM_SYNCPAGE_MODIFIED_PDE)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VINF_SUCCESS;
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync STAM_STATS({ if (!pVM->pgm.s.CTXSUFF(pStatTrap0eAttribution))
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync pVM->pgm.s.CTXSUFF(pStatTrap0eAttribution) = &pVM->pgm.s.StatTrap0eMisc; });
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync STAM_PROFILE_STOP_EX(&pVM->pgm.s.StatGCTrap0e, pVM->pgm.s.CTXSUFF(pStatTrap0eAttribution), a);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync