VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/PGMR0.cpp@ 13343

Last change on this file since 13343 was 13236, checked in by vboxsync, 16 years ago

#1865: More polish.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1/* $Id: PGMR0.cpp 13236 2008-10-13 21:25:50Z vboxsync $ */
2/** @file
3 * PGM - Page Manager and Monitor, Ring-0.
4 */
5
6/*
7 * Copyright (C) 2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#define LOG_GROUP LOG_GROUP_PGM
26#include <VBox/pgm.h>
27#include "PGMInternal.h"
28#include <VBox/vm.h>
29#include <VBox/log.h>
30#include <VBox/err.h>
31#include <iprt/assert.h>
32
33__BEGIN_DECLS
34#define PGM_BTH_NAME(name) PGM_BTH_NAME_32BIT_PROT(name)
35#include "PGMR0Bth.h"
36#undef PGM_BTH_NAME
37
38#define PGM_BTH_NAME(name) PGM_BTH_NAME_PAE_PROT(name)
39#include "PGMR0Bth.h"
40#undef PGM_BTH_NAME
41
42#define PGM_BTH_NAME(name) PGM_BTH_NAME_AMD64_PROT(name)
43#include "PGMR0Bth.h"
44#undef PGM_BTH_NAME
45
46#define PGM_BTH_NAME(name) PGM_BTH_NAME_EPT_PROT(name)
47#include "PGMR0Bth.h"
48#undef PGM_BTH_NAME
49
50__END_DECLS
51
52
53/**
54 * Worker function for PGMR3PhysAllocateHandyPages and pgmPhysEnsureHandyPage.
55 *
56 * @returns The following VBox status codes.
57 * @retval VINF_SUCCESS on success. FF cleared.
58 * @retval VINF_EM_NO_MEMORY if we're out of memory. The FF is set in this case.
59 *
60 * @param pVM The VM handle.
61 *
62 * @remarks Must be called from within the PGM critical section.
63 */
64VMMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM)
65{
66 return VERR_NOT_IMPLEMENTED;
67}
68
69
70/**
71 * #PF Handler for nested paging.
72 *
73 * @returns VBox status code (appropriate for trap handling and GC return).
74 * @param pVM VM Handle.
75 * @param enmShwPagingMode Paging mode for the nested page tables
76 * @param uErr The trap error code.
77 * @param pRegFrame Trap register frame.
78 * @param pvFault The fault address.
79 */
80VMMR0DECL(int) PGMR0Trap0eHandlerNestedPaging(PVM pVM, PGMMODE enmShwPagingMode, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPHYS pvFault)
81{
82 int rc;
83
84 LogFlow(("PGMTrap0eHandler: uErr=%#x pvFault=%VGp eip=%VGv\n", uErr, pvFault, pRegFrame->rip));
85 STAM_PROFILE_START(&pVM->pgm.s.StatRZTrap0e, a);
86 STAM_STATS({ pVM->pgm.s.CTX_SUFF(pStatTrap0eAttribution) = NULL; } );
87
88 /* AMD uses the host's paging mode; Intel has a single mode (EPT). */
89 AssertMsg(enmShwPagingMode == PGMMODE_32_BIT || enmShwPagingMode == PGMMODE_PAE || enmShwPagingMode == PGMMODE_PAE_NX || enmShwPagingMode == PGMMODE_AMD64 || enmShwPagingMode == PGMMODE_AMD64_NX || enmShwPagingMode == PGMMODE_EPT, ("enmShwPagingMode=%d\n", enmShwPagingMode));
90
91#ifdef VBOX_WITH_STATISTICS
92 /*
93 * Error code stats.
94 */
95 if (uErr & X86_TRAP_PF_US)
96 {
97 if (!(uErr & X86_TRAP_PF_P))
98 {
99 if (uErr & X86_TRAP_PF_RW)
100 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eUSNotPresentWrite);
101 else
102 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eUSNotPresentRead);
103 }
104 else if (uErr & X86_TRAP_PF_RW)
105 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eUSWrite);
106 else if (uErr & X86_TRAP_PF_RSVD)
107 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eUSReserved);
108 else if (uErr & X86_TRAP_PF_ID)
109 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eUSNXE);
110 else
111 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eUSRead);
112 }
113 else
114 { /* Supervisor */
115 if (!(uErr & X86_TRAP_PF_P))
116 {
117 if (uErr & X86_TRAP_PF_RW)
118 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eSVNotPresentWrite);
119 else
120 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eSVNotPresentRead);
121 }
122 else if (uErr & X86_TRAP_PF_RW)
123 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eSVWrite);
124 else if (uErr & X86_TRAP_PF_ID)
125 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eSNXE);
126 else if (uErr & X86_TRAP_PF_RSVD)
127 STAM_COUNTER_INC(&pVM->pgm.s.StatRZTrap0eSVReserved);
128 }
129#endif
130
131 /*
132 * Call the worker.
133 *
134 * We pretend the guest is in protected mode without paging, so we can use existing code to build the
135 * nested page tables.
136 */
137 switch(enmShwPagingMode)
138 {
139 case PGMMODE_32_BIT:
140 rc = PGM_BTH_NAME_32BIT_PROT(Trap0eHandler)(pVM, uErr, pRegFrame, pvFault);
141 break;
142 case PGMMODE_PAE:
143 case PGMMODE_PAE_NX:
144 rc = PGM_BTH_NAME_PAE_PROT(Trap0eHandler)(pVM, uErr, pRegFrame, pvFault);
145 break;
146 case PGMMODE_AMD64:
147 case PGMMODE_AMD64_NX:
148 rc = PGM_BTH_NAME_AMD64_PROT(Trap0eHandler)(pVM, uErr, pRegFrame, pvFault);
149 break;
150 case PGMMODE_EPT:
151 rc = PGM_BTH_NAME_EPT_PROT(Trap0eHandler)(pVM, uErr, pRegFrame, pvFault);
152 break;
153 default:
154 AssertFailed();
155 rc = VERR_INVALID_PARAMETER;
156 break;
157 }
158 if (rc == VINF_PGM_SYNCPAGE_MODIFIED_PDE)
159 rc = VINF_SUCCESS;
160 STAM_STATS({ if (!pVM->pgm.s.CTX_SUFF(pStatTrap0eAttribution))
161 pVM->pgm.s.CTX_SUFF(pStatTrap0eAttribution) = &pVM->pgm.s.StatRZTrap0eTime2Misc; });
162 STAM_PROFILE_STOP_EX(&pVM->pgm.s.StatRZTrap0e, pVM->pgm.s.CTX_SUFF(pStatTrap0eAttribution), a);
163 return rc;
164}
165
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette