VirtualBox

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

Last change on this file since 20961 was 19015, checked in by vboxsync, 15 years ago

Split up TRPM. (guest SMP)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.7 KB
Line 
1/* $Id: MMRamGC.cpp 19015 2009-04-20 07:54:29Z 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 PVMCPU pVCpu = VMMGetCpu0(pVM);
107
108 TRPMSaveTrap(pVCpu); /* save the current trap info, because it will get trashed if our access failed. */
109
110 MMGCRamRegisterTrapHandler(pVM);
111 rc = MMGCRamReadNoTrapHandler(pDst, pSrc, cb);
112 MMGCRamDeregisterTrapHandler(pVM);
113 if (RT_FAILURE(rc))
114 TRPMRestoreTrap(pVCpu);
115
116 return rc;
117}
118
119
120/**
121 * Write data in guest context with #PF control.
122 *
123 * @returns VBox status.
124 * @param pVM The VM handle.
125 * @param pDst Where to write the data.
126 * @param pSrc Pointer to the data to write.
127 * @param cb Size of data to write, only 1/2/4 is valid.
128 */
129VMMRCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb)
130{
131 PVMCPU pVCpu = VMMGetCpu0(pVM);
132 TRPMSaveTrap(pVCpu); /* save the current trap info, because it will get trashed if our access failed. */
133
134 MMGCRamRegisterTrapHandler(pVM);
135 int rc = MMGCRamWriteNoTrapHandler(pDst, pSrc, cb);
136 MMGCRamDeregisterTrapHandler(pVM);
137 if (RT_FAILURE(rc))
138 TRPMRestoreTrap(pVCpu);
139
140 /*
141 * And mark the relevant guest page as accessed and dirty.
142 */
143 PGMGstModifyPage(VMMGetCpu0(pVM), (RTGCPTR)(RTRCUINTPTR)pDst, cb, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
144
145 return rc;
146}
147
148
149/**
150 * \#PF Handler for servicing traps inside MMGCRamReadNoTrapHandler and MMGCRamWriteNoTrapHandler functions.
151 *
152 * @internal
153 */
154DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
155{
156 /*
157 * Page fault inside MMGCRamRead()? Resume at *_Error.
158 */
159 if ( (uintptr_t)&MMGCRamReadNoTrapHandler < (uintptr_t)pRegFrame->eip
160 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamReadNoTrapHandler_EndProc)
161 {
162 /* Must be a read violation. */
163 AssertReturn(!(TRPMGetErrorCode(VMMGetCpu0(pVM)) & X86_TRAP_PF_RW), VERR_INTERNAL_ERROR);
164 pRegFrame->eip = (uintptr_t)&MMGCRamRead_Error;
165 return VINF_SUCCESS;
166 }
167
168 /*
169 * Page fault inside MMGCRamWrite()? Resume at _Error.
170 */
171 if ( (uintptr_t)&MMGCRamWriteNoTrapHandler < (uintptr_t)pRegFrame->eip
172 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamWriteNoTrapHandler_EndProc)
173 {
174 /* Must be a write violation. */
175 AssertReturn(TRPMGetErrorCode(VMMGetCpu0(pVM)) & X86_TRAP_PF_RW, VERR_INTERNAL_ERROR);
176 pRegFrame->eip = (uintptr_t)&MMGCRamWrite_Error;
177 return VINF_SUCCESS;
178 }
179
180 /*
181 * Page fault inside EMGCEmulateLockCmpXchg()? Resume at _Error.
182 */
183 if ( (uintptr_t)&EMGCEmulateLockCmpXchg < (uintptr_t)pRegFrame->eip
184 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg_EndProc)
185 {
186 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg_Error;
187 return VINF_SUCCESS;
188 }
189
190 /*
191 * Page fault inside EMGCEmulateCmpXchg()? Resume at _Error.
192 */
193 if ( (uintptr_t)&EMGCEmulateCmpXchg < (uintptr_t)pRegFrame->eip
194 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg_EndProc)
195 {
196 pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg_Error;
197 return VINF_SUCCESS;
198 }
199
200 /*
201 * Page fault inside EMGCEmulateLockCmpXchg8b()? Resume at _Error.
202 */
203 if ( (uintptr_t)&EMGCEmulateLockCmpXchg8b < (uintptr_t)pRegFrame->eip
204 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg8b_EndProc)
205 {
206 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg8b_Error;
207 return VINF_SUCCESS;
208 }
209
210 /*
211 * Page fault inside EMGCEmulateCmpXchg8b()? Resume at _Error.
212 */
213 if ( (uintptr_t)&EMGCEmulateCmpXchg8b < (uintptr_t)pRegFrame->eip
214 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg8b_EndProc)
215 {
216 pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg8b_Error;
217 return VINF_SUCCESS;
218 }
219
220 /*
221 * Page fault inside EMGCEmulateLockXAdd()? Resume at _Error.
222 */
223 if ( (uintptr_t)&EMGCEmulateLockXAdd < (uintptr_t)pRegFrame->eip
224 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockXAdd_EndProc)
225 {
226 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockXAdd_Error;
227 return VINF_SUCCESS;
228 }
229
230 /*
231 * Page fault inside EMGCEmulateXAdd()? Resume at _Error.
232 */
233 if ( (uintptr_t)&EMGCEmulateXAdd < (uintptr_t)pRegFrame->eip
234 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateXAdd_EndProc)
235 {
236 pRegFrame->eip = (uintptr_t)&EMGCEmulateXAdd_Error;
237 return VINF_SUCCESS;
238 }
239
240 /*
241 * Page fault inside EMEmulateLockOr()? Resume at *_Error.
242 */
243 if ( (uintptr_t)&EMEmulateLockOr < (uintptr_t)pRegFrame->eip
244 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockOr_EndProc)
245 {
246 pRegFrame->eip = (uintptr_t)&EMEmulateLockOr_Error;
247 return VINF_SUCCESS;
248 }
249
250 /*
251 * Page fault inside EMEmulateLockBtr()? Resume at *_Error.
252 */
253 if ( (uintptr_t)&EMEmulateLockBtr < (uintptr_t)pRegFrame->eip
254 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockBtr_EndProc)
255 {
256 pRegFrame->eip = (uintptr_t)&EMEmulateLockBtr_Error;
257 return VINF_SUCCESS;
258 }
259
260 /*
261 * #PF is not handled - cause guru meditation.
262 */
263 return VERR_INTERNAL_ERROR;
264}
265
266
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