VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/MMRamGC.cpp@ 18927

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

Big step to separate VMM data structures for guest SMP. (pgm, em)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.6 KB
Line 
1/* $Id: MMRamGC.cpp 18927 2009-04-16 11:41:38Z vboxsync $ */
2/** @file
3 * MMRamGC - Guest Context Ram access Routines, pair for MMRamGCA.asm.
4 */
5
6/*
7 * Copyright (C) 2006-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/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_MM
27#include <VBox/mm.h>
28#include <VBox/cpum.h>
29#include <VBox/trpm.h>
30#include <VBox/em.h>
31#include "MMInternal.h"
32#include <VBox/vm.h>
33#include <VBox/vmm.h>
34#include <VBox/pgm.h>
35
36#include <iprt/assert.h>
37#include <VBox/param.h>
38#include <VBox/err.h>
39
40
41/*******************************************************************************
42* Internal Functions *
43*******************************************************************************/
44static DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame);
45
46DECLASM(void) MMGCRamReadNoTrapHandler_EndProc(void);
47DECLASM(void) MMGCRamWriteNoTrapHandler_EndProc(void);
48DECLASM(void) EMGCEmulateLockCmpXchg_EndProc(void);
49DECLASM(void) EMGCEmulateLockCmpXchg_Error(void);
50DECLASM(void) EMGCEmulateCmpXchg_EndProc(void);
51DECLASM(void) EMGCEmulateCmpXchg_Error(void);
52DECLASM(void) EMGCEmulateLockCmpXchg8b_EndProc(void);
53DECLASM(void) EMGCEmulateLockCmpXchg8b_Error(void);
54DECLASM(void) EMGCEmulateCmpXchg8b_EndProc(void);
55DECLASM(void) EMGCEmulateCmpXchg8b_Error(void);
56DECLASM(void) EMGCEmulateLockXAdd_EndProc(void);
57DECLASM(void) EMGCEmulateLockXAdd_Error(void);
58DECLASM(void) EMGCEmulateXAdd_EndProc(void);
59DECLASM(void) EMGCEmulateXAdd_Error(void);
60DECLASM(void) EMEmulateLockOr_EndProc(void);
61DECLASM(void) EMEmulateLockOr_Error(void);
62DECLASM(void) EMEmulateLockBtr_EndProc(void);
63DECLASM(void) EMEmulateLockBtr_Error(void);
64DECLASM(void) MMGCRamRead_Error(void);
65DECLASM(void) MMGCRamWrite_Error(void);
66
67
68/**
69 * Install MMGCRam Hypervisor page fault handler for normal working
70 * of MMGCRamRead and MMGCRamWrite calls.
71 * This handler will be automatically removed at page fault.
72 * In other case it must be removed by MMGCRamDeregisterTrapHandler call.
73 *
74 * @param pVM VM handle.
75 */
76VMMRCDECL(void) MMGCRamRegisterTrapHandler(PVM pVM)
77{
78 TRPMGCSetTempHandler(pVM, 0xe, mmGCRamTrap0eHandler);
79}
80
81
82/**
83 * Remove MMGCRam Hypervisor page fault handler.
84 * See description of MMGCRamRegisterTrapHandler call.
85 *
86 * @param pVM VM handle.
87 */
88VMMRCDECL(void) MMGCRamDeregisterTrapHandler(PVM pVM)
89{
90 TRPMGCSetTempHandler(pVM, 0xe, NULL);
91}
92
93
94/**
95 * Read data in guest context with #PF control.
96 *
97 * @returns VBox status.
98 * @param pVM The VM handle.
99 * @param pDst Where to store the readed data.
100 * @param pSrc Pointer to the data to read.
101 * @param cb Size of data to read, only 1/2/4/8 is valid.
102 */
103VMMRCDECL(int) MMGCRamRead(PVM pVM, void *pDst, void *pSrc, size_t cb)
104{
105 int rc;
106
107 TRPMSaveTrap(pVM); /* save the current trap info, because it will get trashed if our access failed. */
108
109 MMGCRamRegisterTrapHandler(pVM);
110 rc = MMGCRamReadNoTrapHandler(pDst, pSrc, cb);
111 MMGCRamDeregisterTrapHandler(pVM);
112 if (RT_FAILURE(rc))
113 TRPMRestoreTrap(pVM);
114
115 return rc;
116}
117
118
119/**
120 * Write data in guest context with #PF control.
121 *
122 * @returns VBox status.
123 * @param pVM The VM handle.
124 * @param pDst Where to write the data.
125 * @param pSrc Pointer to the data to write.
126 * @param cb Size of data to write, only 1/2/4 is valid.
127 */
128VMMRCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb)
129{
130 TRPMSaveTrap(pVM); /* save the current trap info, because it will get trashed if our access failed. */
131
132 MMGCRamRegisterTrapHandler(pVM);
133 int rc = MMGCRamWriteNoTrapHandler(pDst, pSrc, cb);
134 MMGCRamDeregisterTrapHandler(pVM);
135 if (RT_FAILURE(rc))
136 TRPMRestoreTrap(pVM);
137
138 /*
139 * And mark the relevant guest page as accessed and dirty.
140 */
141 PGMGstModifyPage(pVM, VMMGetCpu0(pVM), (RTGCPTR)(RTRCUINTPTR)pDst, cb, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
142
143 return rc;
144}
145
146
147/**
148 * \#PF Handler for servicing traps inside MMGCRamReadNoTrapHandler and MMGCRamWriteNoTrapHandler functions.
149 *
150 * @internal
151 */
152DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
153{
154 /*
155 * Page fault inside MMGCRamRead()? Resume at *_Error.
156 */
157 if ( (uintptr_t)&MMGCRamReadNoTrapHandler < (uintptr_t)pRegFrame->eip
158 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamReadNoTrapHandler_EndProc)
159 {
160 /* Must be a read violation. */
161 AssertReturn(!(TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW), VERR_INTERNAL_ERROR);
162 pRegFrame->eip = (uintptr_t)&MMGCRamRead_Error;
163 return VINF_SUCCESS;
164 }
165
166 /*
167 * Page fault inside MMGCRamWrite()? Resume at _Error.
168 */
169 if ( (uintptr_t)&MMGCRamWriteNoTrapHandler < (uintptr_t)pRegFrame->eip
170 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamWriteNoTrapHandler_EndProc)
171 {
172 /* Must be a write violation. */
173 AssertReturn(TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW, VERR_INTERNAL_ERROR);
174 pRegFrame->eip = (uintptr_t)&MMGCRamWrite_Error;
175 return VINF_SUCCESS;
176 }
177
178 /*
179 * Page fault inside EMGCEmulateLockCmpXchg()? Resume at _Error.
180 */
181 if ( (uintptr_t)&EMGCEmulateLockCmpXchg < (uintptr_t)pRegFrame->eip
182 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg_EndProc)
183 {
184 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg_Error;
185 return VINF_SUCCESS;
186 }
187
188 /*
189 * Page fault inside EMGCEmulateCmpXchg()? Resume at _Error.
190 */
191 if ( (uintptr_t)&EMGCEmulateCmpXchg < (uintptr_t)pRegFrame->eip
192 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg_EndProc)
193 {
194 pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg_Error;
195 return VINF_SUCCESS;
196 }
197
198 /*
199 * Page fault inside EMGCEmulateLockCmpXchg8b()? Resume at _Error.
200 */
201 if ( (uintptr_t)&EMGCEmulateLockCmpXchg8b < (uintptr_t)pRegFrame->eip
202 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg8b_EndProc)
203 {
204 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg8b_Error;
205 return VINF_SUCCESS;
206 }
207
208 /*
209 * Page fault inside EMGCEmulateCmpXchg8b()? Resume at _Error.
210 */
211 if ( (uintptr_t)&EMGCEmulateCmpXchg8b < (uintptr_t)pRegFrame->eip
212 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg8b_EndProc)
213 {
214 pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg8b_Error;
215 return VINF_SUCCESS;
216 }
217
218 /*
219 * Page fault inside EMGCEmulateLockXAdd()? Resume at _Error.
220 */
221 if ( (uintptr_t)&EMGCEmulateLockXAdd < (uintptr_t)pRegFrame->eip
222 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockXAdd_EndProc)
223 {
224 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockXAdd_Error;
225 return VINF_SUCCESS;
226 }
227
228 /*
229 * Page fault inside EMGCEmulateXAdd()? Resume at _Error.
230 */
231 if ( (uintptr_t)&EMGCEmulateXAdd < (uintptr_t)pRegFrame->eip
232 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateXAdd_EndProc)
233 {
234 pRegFrame->eip = (uintptr_t)&EMGCEmulateXAdd_Error;
235 return VINF_SUCCESS;
236 }
237
238 /*
239 * Page fault inside EMEmulateLockOr()? Resume at *_Error.
240 */
241 if ( (uintptr_t)&EMEmulateLockOr < (uintptr_t)pRegFrame->eip
242 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockOr_EndProc)
243 {
244 pRegFrame->eip = (uintptr_t)&EMEmulateLockOr_Error;
245 return VINF_SUCCESS;
246 }
247
248 /*
249 * Page fault inside EMEmulateLockBtr()? Resume at *_Error.
250 */
251 if ( (uintptr_t)&EMEmulateLockBtr < (uintptr_t)pRegFrame->eip
252 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockBtr_EndProc)
253 {
254 pRegFrame->eip = (uintptr_t)&EMEmulateLockBtr_Error;
255 return VINF_SUCCESS;
256 }
257
258 /*
259 * #PF is not handled - cause guru meditation.
260 */
261 return VERR_INTERNAL_ERROR;
262}
263
264
Note: See TracBrowser for help on using the repository browser.

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