VirtualBox

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

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

Type and cast corrections

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