VirtualBox

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

Last change on this file since 5953 was 5384, checked in by vboxsync, 17 years ago

LOCK BTR and LOCK OR (for Solaris guests).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.7 KB
Line 
1/* $Id: MMRamGC.cpp 5384 2007-10-19 14:13:42Z vboxsync $ */
2/** @file
3 * MMRamGC - Guest Context Ram access Routines, pair for MMRamGCA.asm.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_MM
23#include <VBox/mm.h>
24#include <VBox/cpum.h>
25#include <VBox/trpm.h>
26#include <VBox/em.h>
27#include "MMInternal.h"
28#include <VBox/vm.h>
29#include <VBox/pgm.h>
30
31#include <iprt/assert.h>
32#include <VBox/param.h>
33#include <VBox/err.h>
34
35
36/*******************************************************************************
37* Internal Functions *
38*******************************************************************************/
39static DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame);
40
41DECLASM(void) MMGCRamReadNoTrapHandler_EndProc(void);
42DECLASM(void) MMGCRamWriteNoTrapHandler_EndProc(void);
43DECLASM(void) EMGCEmulateLockCmpXchg_EndProc(void);
44DECLASM(void) EMGCEmulateLockCmpXchg_Error(void);
45DECLASM(void) EMGCEmulateCmpXchg_EndProc(void);
46DECLASM(void) EMGCEmulateCmpXchg_Error(void);
47DECLASM(void) EMEmulateLockOr_EndProc(void);
48DECLASM(void) EMEmulateLockOr_Error(void);
49DECLASM(void) EMEmulateLockBtr_EndProc(void);
50DECLASM(void) EMEmulateLockBtr_Error(void);
51DECLASM(void) MMGCRamRead_Error(void);
52DECLASM(void) MMGCRamWrite_Error(void);
53
54
55/**
56 * Install MMGCRam Hypervisor page fault handler for normal working
57 * of MMGCRamRead and MMGCRamWrite calls.
58 * This handler will be automatically removed at page fault.
59 * In other case it must be removed by MMGCRamDeregisterTrapHandler call.
60 *
61 * @param pVM VM handle.
62 */
63MMGCDECL(void) MMGCRamRegisterTrapHandler(PVM pVM)
64{
65 TRPMGCSetTempHandler(pVM, 0xe, mmGCRamTrap0eHandler);
66}
67
68/**
69 * Remove MMGCRam Hypervisor page fault handler.
70 * See description of MMGCRamRegisterTrapHandler call.
71 *
72 * @param pVM VM handle.
73 */
74MMGCDECL(void) MMGCRamDeregisterTrapHandler(PVM pVM)
75{
76 TRPMGCSetTempHandler(pVM, 0xe, NULL);
77}
78
79
80/**
81 * Read data in guest context with #PF control.
82 *
83 * @returns VBox status.
84 * @param pVM The VM handle.
85 * @param pDst Where to store the readed data.
86 * @param pSrc Pointer to the data to read.
87 * @param cb Size of data to read, only 1/2/4/8 is valid.
88 */
89MMGCDECL(int) MMGCRamRead(PVM pVM, void *pDst, void *pSrc, size_t cb)
90{
91 int rc;
92
93 TRPMSaveTrap(pVM); /* save the current trap info, because it will get trashed if our access failed. */
94
95 MMGCRamRegisterTrapHandler(pVM);
96 rc = MMGCRamReadNoTrapHandler(pDst, pSrc, cb);
97 MMGCRamDeregisterTrapHandler(pVM);
98 if (VBOX_FAILURE(rc))
99 TRPMRestoreTrap(pVM);
100
101 return rc;
102}
103
104/**
105 * Write data in guest context with #PF control.
106 *
107 * @returns VBox status.
108 * @param pVM The VM handle.
109 * @param pDst Where to write the data.
110 * @param pSrc Pointer to the data to write.
111 * @param cb Size of data to write, only 1/2/4 is valid.
112 */
113MMGCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb)
114{
115 int rc;
116
117 TRPMSaveTrap(pVM); /* save the current trap info, because it will get trashed if our access failed. */
118
119 MMGCRamRegisterTrapHandler(pVM);
120 rc = MMGCRamWriteNoTrapHandler(pDst, pSrc, cb);
121 MMGCRamDeregisterTrapHandler(pVM);
122 if (VBOX_FAILURE(rc))
123 TRPMRestoreTrap(pVM);
124
125 /*
126 * And mark the relevant guest page as accessed and dirty.
127 */
128 PGMGstModifyPage(pVM, pDst, cb, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
129
130 return rc;
131}
132
133
134/**
135 * \#PF Handler for servicing traps inside MMGCRamReadNoTrapHandler and MMGCRamWriteNoTrapHandler functions.
136 *
137 * @internal
138 */
139DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
140{
141 /*
142 * Page fault inside MMGCRamRead()? Resume at *_Error.
143 */
144 if ( (uintptr_t)&MMGCRamReadNoTrapHandler < (uintptr_t)pRegFrame->eip
145 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamReadNoTrapHandler_EndProc)
146 {
147 /* Must be a read violation. */
148 AssertReturn(!(TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW), VERR_INTERNAL_ERROR);
149 pRegFrame->eip = (uintptr_t)&MMGCRamRead_Error;
150 return VINF_SUCCESS;
151 }
152
153 /*
154 * Page fault inside MMGCRamWrite()? Resume at _Error.
155 */
156 if ( (uintptr_t)&MMGCRamWriteNoTrapHandler < (uintptr_t)pRegFrame->eip
157 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamWriteNoTrapHandler_EndProc)
158 {
159 /* Must be a write violation. */
160 AssertReturn(TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW, VERR_INTERNAL_ERROR);
161 pRegFrame->eip = (uintptr_t)&MMGCRamWrite_Error;
162 return VINF_SUCCESS;
163 }
164
165 /*
166 * Page fault inside EMGCEmulateLockCmpXchg()? Resume at _Error.
167 */
168 if ( (uintptr_t)&EMGCEmulateLockCmpXchg < (uintptr_t)pRegFrame->eip
169 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg_EndProc)
170 {
171 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg_Error;
172 return VINF_SUCCESS;
173 }
174
175 /*
176 * Page fault inside EMGCEmulateCmpXchg()? Resume at _Error.
177 */
178 if ( (uintptr_t)&EMGCEmulateCmpXchg < (uintptr_t)pRegFrame->eip
179 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg_EndProc)
180 {
181 pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg_Error;
182 return VINF_SUCCESS;
183 }
184
185 /*
186 * Page fault inside EMEmulateLockOr()? Resume at *_Error.
187 */
188 if ( (uintptr_t)&EMEmulateLockOr < (uintptr_t)pRegFrame->eip
189 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockOr_EndProc)
190 {
191 pRegFrame->eip = (uintptr_t)&EMEmulateLockOr_Error;
192 return VINF_SUCCESS;
193 }
194
195 /*
196 * Page fault inside EMEmulateLockBtr()? Resume at *_Error.
197 */
198 if ( (uintptr_t)&EMEmulateLockBtr < (uintptr_t)pRegFrame->eip
199 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockBtr_EndProc)
200 {
201 pRegFrame->eip = (uintptr_t)&EMEmulateLockBtr_Error;
202 return VINF_SUCCESS;
203 }
204
205 /*
206 * #PF is not handled - cause guru meditation.
207 */
208 return VERR_INTERNAL_ERROR;
209}
210
211
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