VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/REMAll.cpp@ 20746

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

REMR3ReplayHandlerNotification,remNotifyHandlerInsert: paranoia.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.1 KB
Line 
1/* $Id: REMAll.cpp 20746 2009-06-21 19:53:12Z vboxsync $ */
2/** @file
3 * REM - Recompiled Execution Monitor, all Contexts part.
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* Global Variables *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_REM
27#include <VBox/rem.h>
28#include <VBox/em.h>
29#include <VBox/vmm.h>
30#include "REMInternal.h"
31#include <VBox/vm.h>
32#include <VBox/err.h>
33#include <VBox/log.h>
34
35#include <iprt/assert.h>
36
37
38#ifndef IN_RING3
39
40/**
41 * Records a invlpg instruction for replaying upon REM entry.
42 *
43 * @returns VINF_SUCCESS on success.
44 * @param pVM The VM handle.
45 * @param GCPtrPage The
46 */
47VMMDECL(int) REMNotifyInvalidatePage(PVM pVM, RTGCPTR GCPtrPage)
48{
49 if ( pVM->rem.s.cInvalidatedPages < RT_ELEMENTS(pVM->rem.s.aGCPtrInvalidatedPages)
50 && EMTryEnterRemLock(pVM) == VINF_SUCCESS) /* if this fails, then we'll just flush the tlb as we don't want to waste time here. */
51 {
52 /*
53 * We sync them back in REMR3State.
54 */
55 pVM->rem.s.aGCPtrInvalidatedPages[pVM->rem.s.cInvalidatedPages++] = GCPtrPage;
56 EMRemUnlock(pVM);
57 }
58 else
59 {
60 /* Tell the recompiler to flush its TLB. */
61 CPUMSetChangedFlags(VMMGetCpu(pVM), CPUM_CHANGED_GLOBAL_TLB_FLUSH);
62 pVM->rem.s.cInvalidatedPages = 0;
63 }
64
65 return VINF_SUCCESS;
66}
67
68
69/**
70 * Flushes the handler notifications by calling the host.
71 *
72 * @param pVM The VM handle.
73 */
74static void remFlushHandlerNotifications(PVM pVM)
75{
76#ifdef IN_RC
77 VMMGCCallHost(pVM, VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS, 0);
78#elif defined(IN_RING0)
79 /** @todo necessary? */
80 VMMR0CallHost(pVM, VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS, 0);
81#else
82 AssertReleaseMsgFailed(("Ring 3 call????.\n"));
83#endif
84}
85
86
87/**
88 * Insert pending notification
89 *
90 * @param pVM VM Handle.
91 * @param pRec Notification record to insert
92 */
93static void remNotifyHandlerInsert(PVM pVM, PREMHANDLERNOTIFICATION pRec)
94{
95 uint32_t idxFree;
96 uint32_t idxNext;
97 PREMHANDLERNOTIFICATION pFree;
98
99 /* Fetch a free record. */
100 do
101 {
102 idxFree = ASMAtomicUoReadU32(&pVM->rem.s.idxFreeList);
103 if (idxFree == (uint32_t)-1)
104 {
105 pFree = NULL;
106 break;
107 }
108 pFree = &pVM->rem.s.aHandlerNotifications[idxFree];
109 } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxFreeList, pFree->idxNext, idxFree));
110
111 if (!pFree)
112 {
113 remFlushHandlerNotifications(pVM);
114 /** @todo why are we dropping the pReq here without a fight? If we can drop
115 * one, we can drop all... */
116 return;
117 }
118
119 /* Copy the record. */
120 *pFree = *pRec;
121 pFree->idxSelf = idxFree; /* was trashed */
122
123 /* Insert it into the pending list. */
124 do
125 {
126 idxNext = ASMAtomicUoReadU32(&pVM->rem.s.idxPendingList);
127 ASMAtomicWriteU32(&pFree->idxNext, idxNext);
128 ASMCompilerBarrier();
129 } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxPendingList, idxFree, idxNext));
130
131 VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY);
132}
133
134
135/**
136 * Notification about a successful PGMR3HandlerPhysicalRegister() call.
137 *
138 * @param pVM VM Handle.
139 * @param enmType Handler type.
140 * @param GCPhys Handler range address.
141 * @param cb Size of the handler range.
142 * @param fHasHCHandler Set if the handler have a HC callback function.
143 */
144VMMDECL(void) REMNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler)
145{
146 REMHANDLERNOTIFICATION Rec;
147 Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_REGISTER;
148 Rec.u.PhysicalRegister.enmType = enmType;
149 Rec.u.PhysicalRegister.GCPhys = GCPhys;
150 Rec.u.PhysicalRegister.cb = cb;
151 Rec.u.PhysicalRegister.fHasHCHandler = fHasHCHandler;
152 remNotifyHandlerInsert(pVM, &Rec);
153}
154
155
156/**
157 * Notification about a successful PGMR3HandlerPhysicalDeregister() operation.
158 *
159 * @param pVM VM Handle.
160 * @param enmType Handler type.
161 * @param GCPhys Handler range address.
162 * @param cb Size of the handler range.
163 * @param fHasHCHandler Set if the handler have a HC callback function.
164 * @param fRestoreAsRAM Whether the to restore it as normal RAM or as unassigned memory.
165 */
166VMMDECL(void) REMNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
167{
168 REMHANDLERNOTIFICATION Rec;
169 Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_DEREGISTER;
170 Rec.u.PhysicalDeregister.enmType = enmType;
171 Rec.u.PhysicalDeregister.GCPhys = GCPhys;
172 Rec.u.PhysicalDeregister.cb = cb;
173 Rec.u.PhysicalDeregister.fHasHCHandler = fHasHCHandler;
174 Rec.u.PhysicalDeregister.fRestoreAsRAM = fRestoreAsRAM;
175 remNotifyHandlerInsert(pVM, &Rec);
176}
177
178
179/**
180 * Notification about a successful PGMR3HandlerPhysicalModify() call.
181 *
182 * @param pVM VM Handle.
183 * @param enmType Handler type.
184 * @param GCPhysOld Old handler range address.
185 * @param GCPhysNew New handler range address.
186 * @param cb Size of the handler range.
187 * @param fHasHCHandler Set if the handler have a HC callback function.
188 * @param fRestoreAsRAM Whether the to restore it as normal RAM or as unassigned memory.
189 */
190VMMDECL(void) REMNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
191{
192 REMHANDLERNOTIFICATION Rec;
193 Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_MODIFY;
194 Rec.u.PhysicalModify.enmType = enmType;
195 Rec.u.PhysicalModify.GCPhysOld = GCPhysOld;
196 Rec.u.PhysicalModify.GCPhysNew = GCPhysNew;
197 Rec.u.PhysicalModify.cb = cb;
198 Rec.u.PhysicalModify.fHasHCHandler = fHasHCHandler;
199 Rec.u.PhysicalModify.fRestoreAsRAM = fRestoreAsRAM;
200 remNotifyHandlerInsert(pVM, &Rec);
201}
202
203#endif /* !IN_RING3 */
204
205/**
206 * Make REM flush all translation block upon the next call to REMR3State().
207 *
208 * @param pVM Pointer to the shared VM structure.
209 */
210VMMDECL(void) REMFlushTBs(PVM pVM)
211{
212 LogFlow(("REMFlushTBs: fFlushTBs=%RTbool fInREM=%RTbool fInStateSync=%RTbool\n",
213 pVM->rem.s.fFlushTBs, pVM->rem.s.fInREM, pVM->rem.s.fInStateSync));
214 pVM->rem.s.fFlushTBs = true;
215}
216
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