VirtualBox

source: vbox/trunk/src/VBox/VMM/PGMCache.h@ 1249

Last change on this file since 1249 was 23, checked in by vboxsync, 18 years ago

string.h & stdio.h + header cleanups.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.1 KB
Line 
1/* $Id: PGMCache.h 23 2007-01-15 14:08:28Z vboxsync $ */
2/** @file
3 * VBox - PGM PD Cache Manager
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung 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 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#ifndef __PGMCache_h__
23#define __PGMCache_h__
24
25#if !defined(IN_PGM_R3) && !defined(IN_PGM_R0) && !defined(IN_PGM_GC)
26# error "Not in PGM! This is an internal header!"
27#endif
28
29#define PGMCACHE_PHYSREG_DESCRIPTION "PGM Cache PT write handler"
30
31#define PGMCACHE_MAX_CACHED_PDES 32
32#define PGMCACHE_MAX_CACHED_ENTRIES 8
33#define PGMCACHE_INVALID_INDEX 0xffffffff
34
35#define PGMCACHE_FILL_THRESHOLD 5000
36//#define PGMCACHE_FILL_THRESHOLD 500
37#define PGMCACHE_INSERT_BOOST 500
38
39#define PGMCACHE_SYNCPT_USER_INC 10
40#define PGMCACHE_SYNCPT_SUPERVISOR_INC 20
41#define PGMCACHE_SYNCPAGE_USER_INC 1
42#define PGMCACHE_SYNCPAGE_SUPERVISOR_INC 2
43#define PGMCACHE_CACHE_HIT_INC 50
44#define PGMCACHE_LEAVEGC_DEC -1
45#define PGMCACHE_SIGNIFICANT_PTWRITE_DEC -5
46#define PGMCACHE_PTWRITE_DEC -2
47#define PGMCACHE_UNKNOWN_PTWRITE_DEC -100
48#define PGMCACHE_PDE_CHANGE_DEC -250
49#define PGMCACHE_PDE_CR3_MAPPING -2500
50#define PGMCACHE_PDE_CONFLICT_DEC -1000
51#define PGMCACHE_PDE_CHANGE_HIT_INC (PGMCACHE_CACHE_HIT_INC)
52#define PGMCACHE_MAX_DIRTY_PAGES 4
53
54
55/* define to enable PD caching */
56//#define PGM_PD_CACHING_ENABLED
57#ifdef VBOX_STRICT
58/* define to enable strict PD checking */
59//#define PGM_CACHE_STRICT
60/* define to enable paranoid checking */
61//#define PGM_CACHE_VERY_STRICT
62// #define PGM_CACHE_EXTREMELY_STRICT
63#endif
64
65#define PGMCACHE_GET_ACTIVE_ENTRY(pLine) \
66 (pLine->iActiveEntry != PGMCACHE_INVALID_INDEX) ? &pLine->entry[pLine->iActiveEntry] : NULL
67
68typedef struct
69{
70 /* Caching score */
71 unsigned u29Score : 29;
72 /* PD is waiting to be cached */
73 unsigned u1Queued : 1;
74 /* PD is cached */
75 unsigned u1Cached : 1;
76 /* Cache disabled flag */
77 unsigned u1CacheDisabled : 1;
78} PDESTAT, *PPDESTAT;
79
80typedef struct
81{
82 /* Copy of guest PDE */
83 X86PDEPAE PdeGst;
84 /* Shadow PT physical address */
85 RTGCPHYS PtShwPhys;
86
87 /* Multiple dirty accesses -> flush entry */
88 bool fDirtyFlush;
89 /* Dirty flag */
90 bool fDirty;
91 /* Dirty state is pending until the PD is activated */
92 bool fDirtyPending;
93
94 /* GC address of PT write */
95 RTGCUINTPTR pvFaultDirty[PGMCACHE_MAX_DIRTY_PAGES];
96 uint32_t cNumDirtyPages;
97
98 /* Cache entry score */
99 uint32_t uScore;
100
101 /* Cache line index */
102 uint32_t iLine;
103 /* Cache entry index */
104 uint32_t iEntry;
105} PDCACHEENTRY, *PPDCACHEENTRY;
106
107typedef struct
108{
109 /* Shadow page directory index (0-2047, PGMCACHE_INVALID_INDEX when unused) */
110 uint32_t iPDShw;
111 /* Guest context address that corresponds to the shadow iPD */
112 RTGCUINTPTR GCPtrPDE;
113
114 /* Set when the cache entry is modified */
115 bool fRefresh;
116
117 uint32_t iPDShwNew;
118 uint32_t iPDShwOld;
119 /* Currently used cache entry */
120 uint32_t iActiveEntry;
121 /* Cache index line */
122 uint32_t iLine;
123
124 PDCACHEENTRY entry[PGMCACHE_MAX_CACHED_ENTRIES];
125} PDCACHELINE, *PPDCACHELINE;
126
127
128typedef struct
129{
130 /* Cached PDEs */
131 PDCACHELINE line[PGMCACHE_MAX_CACHED_PDES];
132
133 /* Lowest score of all cached PDEs. */
134 uint32_t ulLowestScore;
135 /* Caching statistics for all PDEs. */
136 PDESTAT pd[2048];
137 /* Set when a cache entry is modified. */
138 bool fChanged;
139 /* Caching enabled. */
140 bool fEnabled;
141 /* Max nr of host PDEs (PAE vs 32 bits). */
142 uint32_t cbMaxPDEs;
143 /* PD shift for host paging. */
144 uint32_t ShwPDShift;
145 /* PD size for host paging. */
146 uint32_t cbShwPD;
147
148#ifdef DEBUG
149 uint32_t cr3;
150 SUPPAGINGMODE enmHostMode;
151#endif
152} PDCACHE, *PPDCACHE;
153
154/**
155 * Initialise PGM caching subsystem
156 *
157 * @returns VBox status code.
158 * @param pVM The virtual machine.
159 * @param enmHostMode Host paging mode
160 */
161int pgmr3CacheInit(PVM pVM, SUPPAGINGMODE enmHostMode);
162
163
164/**
165 * Reset PGM caching subsystem
166 *
167 * @returns VBox status code.
168 * @param pVM The virtual machine.
169 * @param enmHostMode Host paging mode
170 */
171int pgmr3CacheReset(PVM pVM, SUPPAGINGMODE enmHostMode);
172
173
174/**
175 * Inform the PGM Cache Manager when exiting the guest context
176 *
177 * @returns VBox status code.
178 * @param pVM The virtual machine.
179 * @param pCtx Current CPU context
180 * @param u32Reason Reason for exiting the guest context
181 * Currently only for VINF_EM_RAW_INTERRUPT!
182 */
183int pgmr3CacheLeaveGC(PVM pVM, PCPUMCTX pCtx, uint32_t u32Reason);
184
185
186/**
187 * Inform the PGM Cache Manager about a pending Sync PD action (called
188 * from PGMR3SyncPD only!)
189 *
190 * @returns VBox status code.
191 * @param pVM The virtual machine.
192 * @param cr0 Current CR0 register value
193 * @param cr3 Current CR3 register value
194 * @param cr4 Current CR4 register value
195 */
196int pgmr3CacheSyncPD(PVM pVM, uint32_t cr0, uint32_t cr3, uint32_t cr4);
197
198
199/**
200 * Mark all cache lines and entries as dirty.
201 *
202 * @returns VBox status code.
203 * @param pVM The virtual machine.
204 */
205int pgmr3CacheGlobalFlush(PVM pVM);
206
207
208#ifdef VBOX_STRICT
209/**
210 * Checks the guest and shadow tables for consistency.
211 *
212 * @returns VBox status code.
213 * @param pVM The virtual machine.
214 * @param cr0 Current CR0 register value
215 * @param cr3 Current CR3 register value
216 * @param cr4 Current CR4 register value
217 */
218void pgmCacheCheckPD(PVM pVM, uint32_t cr0, uint32_t cr3, uint32_t cr4);
219
220/**
221 * Checks the cache line if it is marked dirty.
222 *
223 * @returns boolean; true if the line is marked dirty, otherwise false
224 * @param pVM The virtual machine.
225 * @param iPDShw Page directory entry
226 */
227bool pgmCacheIsLineDirty(PVM pVM, uint32_t iPDShw);
228
229#else
230#define pgmr3CacheCheckPD(a, b, c, d)
231#define pgmCacheIsLineDirty(a, b) false
232#define pgmCacheCheckPDE(a, b)
233#endif
234
235#ifdef PGM_CACHE_EXTREMELY_STRICT
236/**
237 * Check cache line integrity
238 *
239 * @param pVM The virtual machine.
240 * @param pLine Cache line
241 * @param pEntry Cache entry
242 */
243void pgmCacheCheckIntegrity(PVM pVM, PPDCACHELINE pLine, PPDCACHEENTRY pEntry);
244#else
245#define pgmCacheCheckIntegrity(a, b, c)
246#endif
247
248/**
249 * Cache PDE
250 *
251 * @returns VBox status code.
252 * @param pVM The virtual machine.
253 * @param iPDShw Page directory index
254 */
255int pgmCacheInsertPD(PVM pVM, uint32_t iPDShw);
256
257/**
258 * Invalidate cached PDE.
259 *
260 * @returns VBox status code.
261 * @param pVM The virtual machine.
262 * @param iLine Cache line index
263 * @param penalty Score penalty for invalidation
264 */
265int pgmCacheInvalidateLine(PVM pVM, uint32_t iLine, int penalty);
266
267
268/**
269 * Invalidate cached PDE
270 *
271 * @returns VBox status code.
272 * @param pVM The virtual machine.
273 * @param iPDShw PDE index
274 * @param penalty Score penalty for invalidation
275 */
276int pgmCacheInvalidate(PVM pVM, uint32_t iPDShw, int penalty);
277
278
279/**
280 * Invalidate all cached PDEs
281 *
282 * @returns VBox status code.
283 * @param pVM The virtual machine.
284 */
285int pgmCacheInvalidateAll(PVM pVM);
286
287
288/**
289 * Update record for specified PD
290 *
291 * @returns VBox status code.
292 * @param pVM The virtual machine.
293 * @param iPDShw Page directory index
294 * @param delta Score increment/decrement
295 */
296int pgmCacheUpdatePD(PVM pVM, uint32_t iPDShw, int delta);
297
298
299/**
300 * Update record for specified PD
301 *
302 * @returns VBox status code.
303 * @param pVM The virtual machine.
304 * @param iLine Cache line index
305 * @param iEntry Cache entry index
306 * @param delta Score increment/decrement
307 */
308int pgmCacheUpdateEntry(PVM pVM, uint32_t iLine, uint32_t iEntry, int delta);
309
310
311/**
312 * Update record for specified PD + all cache entries
313 *
314 * @returns VBox status code.
315 * @param pVM The virtual machine.
316 * @param iPDShw Page directory index
317 * @param delta Score increment/decrement
318 */
319int pgmCacheUpdateAll(PVM pVM, uint32_t iPDShw, int delta);
320
321
322/**
323 * Remove the handler for the supplied physical page
324 * (@todo maybe this should be a physical range instead )
325 *
326 * @returns VBox status code.
327 * @param pVM The virtual machine.
328 * @param GCPhys GC physical address
329 */
330int pgmCacheRemovePhyshandler(PVM pVM, RTGCPHYS GCPhys);
331
332
333/**
334 * Check if a page directory entry is cached
335 *
336 * @returns true if cached, otherwise false
337 * @param pPdCache PGM cache record pointer
338 * @param iPDShw Page directory index
339 */
340inline bool pgmCacheIsPDCached(PPDCACHE pPdCache, uint32_t iPDShw)
341{
342#ifdef PGM_PD_CACHING_ENABLED
343 if (iPDShw < pPdCache->cbMaxPDEs)
344 {
345 return !!pPdCache->pd[iPDShw].u1Cached;
346 }
347#endif
348 return false;
349}
350
351
352/**
353 * Check if a page directory entry is cached
354 *
355 * @returns true if cached, otherwise false
356 * @param pVM The virtual machine.
357 * @param iPDShw Page directory index
358 */
359bool pgmCacheIsPDCached(PVM pVM, uint32_t iPDShw);
360
361/**
362 * Checks if the PDE has been changed
363 *
364 * @returns boolean
365 * @param pVM The virtual machine.
366 * @param iPDShw Page directory entry
367 */
368bool pgmCacheHasPDEChanged(PVM pVM, uint32_t iPDShw);
369
370/**
371 * Checks if the PDE has been changed
372 *
373 * @returns boolean
374 * @param pVM The virtual machine.
375 * @param pLine Cache line
376 */
377bool pgmCacheHasPDEChanged(PVM pVM, PPDCACHELINE pLine);
378
379/**
380 * Invalidate entry in shadow page directory
381 *
382 * @returns VBox status code.
383 * @param iPDShw PDE index
384 * @param iPDShw Page directory index
385 */
386void pgmInvalidatePD(PVM pVM, uint32_t iPDShw);
387
388
389/**
390 * Activate a cached PD (called by SyncPT when it is synced for the first time).
391 *
392 * @returns VBox status code.
393 * @param pVM The virtual machine.
394 * @param iPDShw PDE index
395 */
396int pgmCacheActivatePD(PVM pVM, uint32_t iPDShw);
397
398/**
399 * Clean up dirty cache entry
400 *
401 * @returns VBox status code.
402 * @param pVM The virtual machine.
403 * @param pLine Cache line pointer
404 * @param pEntry Cache entry pointer
405 */
406int pgmCacheHandleDirtyEntry(PVM pVM, PPDCACHELINE pLine, PPDCACHEENTRY pEntry);
407
408DECLEXPORT(int) pgmCachePTWrite(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
409
410#endif /* !__PGMCache_h__ */
411
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