VirtualBox

source: vbox/trunk/src/VBox/VMM/PATM/CSAMInternal.h@ 3025

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

Added missing space after ')' in macro invocations so VCC doesn't mess up the precompiler output.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.9 KB
Line 
1/* $Id: CSAMInternal.h 3025 2007-06-04 12:49:31Z vboxsync $ */
2/** @file
3 * CSAM - Internal header file.
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 * 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 __CSAMInternal_h__
23#define __CSAMInternal_h__
24
25#include <VBox/cdefs.h>
26#include <VBox/types.h>
27#include <VBox/csam.h>
28#include <VBox/dis.h>
29#include <VBox/log.h>
30
31#if !defined(IN_CSAM_R3) && !defined(IN_CSAM_R0) && !defined(IN_CSAM_GC)
32# error "Not in CSAM! This is an internal header!"
33#endif
34
35/** Page flags.
36 * These are placed in the three bits available for system programs in
37 * the page entries.
38 * @{ */
39#ifndef PGM_PTFLAGS_CSAM_VALIDATED
40/** Scanned and approved by CSAM (tm). */
41/** NOTE: Must be identical to the one defined in PGMInternal.h!! */
42#define PGM_PTFLAGS_CSAM_VALIDATED BIT64(11)
43#endif
44
45/** @} */
46
47#define CSAM_SSM_VERSION 14
48
49#define CSAM_PGDIRBMP_CHUNKS 1024
50
51#define CSAM_PAGE_BITMAP_SIZE (PAGE_SIZE/(sizeof(uint8_t)*8))
52
53/* Maximum nr of dirty page that are cached. */
54#define CSAM_MAX_DIRTY_PAGES 32
55
56/* Maximum number of cached addresses of dangerous instructions that have been scanned before. */
57#define CSAM_MAX_DANGR_INSTR 16 /* power of two! */
58#define CSAM_MAX_DANGR_INSTR_MASK (CSAM_MAX_DANGR_INSTR-1)
59
60/* Maximum number of possible dangerous code pages that we'll flush after a world switch */
61#define CSAM_MAX_CODE_PAGES_FLUSH 32
62
63#define CSAM_MAX_CALLEXIT_RET 16
64
65/* copy from PATMInternal.h */
66#define SIZEOF_NEARJUMP32 5 //opcode byte + 4 byte relative offset
67
68typedef struct
69{
70 RTGCPTR pInstrAfterRetGC[CSAM_MAX_CALLEXIT_RET];
71 uint32_t cInstrAfterRet;
72} CSAMCALLEXITREC, *PCSAMCALLEXITREC;
73
74typedef struct
75{
76 HCPTRTYPE(uint8_t *) pPageLocStartHC;
77 HCPTRTYPE(uint8_t *) pPageLocEndHC;
78 GCPTRTYPE(uint8_t *) pGuestLoc;
79 uint32_t depth; //call/jump depth
80
81 PCSAMCALLEXITREC pCallExitRec;
82} CSAMP2GLOOKUPREC, *PCSAMP2GLOOKUPREC;
83
84typedef struct
85{
86 RTGCPTR pPageGC;
87 RTGCPHYS GCPhys;
88 uint64_t fFlags;
89 uint32_t uSize;
90
91 uint8_t *pBitmap;
92
93 bool fCode32;
94 bool fMonitorActive;
95 bool fMonitorInvalidation;
96
97 CSAMTAG enmTag;
98
99 uint64_t u64Hash;
100} CSAMPAGE, *PCSAMPAGE;
101
102typedef struct
103{
104 // GC Patch pointer
105 RTGCPTR pInstrGC;
106
107 // Disassembly state for original instruction
108 DISCPUSTATE cpu;
109
110 uint32_t uState;
111
112 PCSAMPAGE pPage;
113} CSAMPATCH, *PCSAMPATCH;
114
115/**
116 * Lookup record for CSAM pages
117 */
118typedef struct CSAMPAGEREC
119{
120 /** The key is a GC virtual address. */
121 AVLPVNODECORE Core;
122 CSAMPAGE page;
123
124} CSAMPAGEREC, *PCSAMPAGEREC;
125
126/**
127 * Lookup record for patches
128 */
129typedef struct CSAMPATCHREC
130{
131 /** The key is a GC virtual address. */
132 AVLPVNODECORE Core;
133 CSAMPATCH patch;
134
135} CSAMPATCHREC, *PCSAMPATCHREC;
136
137
138/**
139 * CSAM VM Instance data.
140 * Changes to this must checked against the padding of the CSAM union in VM!
141 * @note change SSM version when changing it!!
142 */
143typedef struct CSAM
144{
145 /** Offset to the VM structure.
146 * See CSAM2VM(). */
147 RTINT offVM;
148#if HC_ARCH_BITS == 64
149 RTINT Alignment0; /**< Align pPageTree correctly. */
150#endif
151
152 HCPTRTYPE(PAVLPVNODECORE) pPageTree;
153
154 /* Array to store previously scanned dangerous instructions, so we don't need to
155 * switch back to ring 3 each time we encounter them in GC.
156 */
157 RTGCPTR aDangerousInstr[CSAM_MAX_DANGR_INSTR];
158 uint32_t cDangerousInstr;
159 uint32_t iDangerousInstr;
160
161 GCPTRTYPE(RTGCPTR *) pPDBitmapGC;
162 GCPTRTYPE(RTHCPTR *) pPDHCBitmapGC;
163 HCPTRTYPE(uint8_t **) pPDBitmapHC;
164 HCPTRTYPE(RTGCPTR *) pPDGCBitmapHC;
165
166 /* Temporary storage during load/save state */
167 struct
168 {
169 HCPTRTYPE(PSSMHANDLE) pSSM;
170 uint32_t cPageRecords;
171 uint32_t cPatchPageRecords;
172 } savedstate;
173
174 /* To keep track of dirty pages */
175 uint32_t cDirtyPages;
176 RTGCPTR pvDirtyBasePage[CSAM_MAX_DIRTY_PAGES];
177 RTGCPTR pvDirtyFaultPage[CSAM_MAX_DIRTY_PAGES];
178
179 /* To keep track of possible code pages */
180 uint32_t cPossibleCodePages;
181 RTGCPTR pvPossibleCodePage[CSAM_MAX_CODE_PAGES_FLUSH];
182
183 /* Set when scanning has started. */
184 bool fScanningStarted;
185
186 /* Set when the IDT gates have been checked for the first time. */
187 bool fGatesChecked;
188 bool Alignment1[HC_ARCH_BITS == 32 ? 4 : 6]; /**< Align the stats on an 8-byte boundrary. */
189
190 STAMCOUNTER StatNrTraps;
191 STAMCOUNTER StatNrPages;
192 STAMCOUNTER StatNrPagesInv;
193 STAMCOUNTER StatNrRemovedPages;
194 STAMCOUNTER StatNrPatchPages;
195 STAMCOUNTER StatNrPageNPHC;
196 STAMCOUNTER StatNrPageNPGC;
197 STAMCOUNTER StatNrFlushes;
198 STAMCOUNTER StatNrFlushesSkipped;
199 STAMCOUNTER StatNrKnownPagesHC;
200 STAMCOUNTER StatNrKnownPagesGC;
201 STAMCOUNTER StatNrInstr;
202 STAMCOUNTER StatNrBytesRead;
203 STAMCOUNTER StatNrOpcodeRead;
204 STAMPROFILE StatTime;
205 STAMPROFILE StatTimeCheckAddr;
206 STAMPROFILE StatTimeAddrConv;
207 STAMPROFILE StatTimeFlushPage;
208 STAMPROFILE StatTimeDisasm;
209 STAMPROFILE StatFlushDirtyPages;
210 STAMPROFILE StatCheckGates;
211 STAMCOUNTER StatCodePageModified;
212 STAMCOUNTER StatDangerousWrite;
213
214 STAMCOUNTER StatInstrCacheHit;
215 STAMCOUNTER StatInstrCacheMiss;
216
217 STAMCOUNTER StatPagePATM;
218 STAMCOUNTER StatPageCSAM;
219 STAMCOUNTER StatPageREM;
220 STAMCOUNTER StatNrUserPages;
221 STAMCOUNTER StatPageMonitor;
222 STAMCOUNTER StatPageRemoveREMFlush;
223
224 STAMCOUNTER StatBitmapAlloc;
225
226 STAMCOUNTER StatScanNextFunction;
227 STAMCOUNTER StatScanNextFunctionFailed;
228} CSAM, *PCSAM;
229
230/**
231 * Call for analyzing the instructions following the privileged instr. for compliance with our heuristics
232 *
233 * @returns VBox status code.
234 * @param pVM The VM to operate on.
235 * @param pCpu CPU disassembly state
236 * @param pInstrHC Guest context pointer to privileged instruction
237 * @param pCurInstrGC Guest context pointer to current instruction
238 * @param pUserData User pointer
239 *
240 */
241typedef int (VBOXCALL *PFN_CSAMR3ANALYSE)(PVM pVM, DISCPUSTATE *pCpu, GCPTRTYPE(uint8_t *) pInstrGC, GCPTRTYPE(uint8_t *) pCurInstrGC, PCSAMP2GLOOKUPREC pCacheRec, void *pUserData);
242
243/**
244 * Check if the current instruction is the start of a known guest block that requires our attention
245 *
246 * @param pVM The VM to operate on.
247 * @param pInstrGC Guest context pointer of instruction to check
248 * @param pInstrHC Host context pointer of instruction to check
249 * @param opcode Opcode of instruction at pInstrGC
250 *
251 * @returns true if patched
252 *
253 */
254bool csamCheckGuestSpecificPatch(PVM pVM, RTGCPTR pInstrGC, HCPTRTYPE(uint8_t *) pInstrHC, uint32_t opcode);
255
256/**
257 * Calculate the branch destination
258 *
259 * @returns branch destination or 0 if failed
260 * @param pCpu Disassembly state of instruction.
261 * @param pBranchInstrGC GC pointer of branch instruction
262 */
263inline RTGCPTR CSAMResolveBranch(PDISCPUSTATE pCpu, RTGCPTR pBranchInstrGC)
264{
265 uint32_t disp;
266 if (pCpu->param1.flags & USE_IMMEDIATE8_REL)
267 {
268 disp = (int32_t)(char)pCpu->param1.parval;
269 }
270 else
271 if (pCpu->param1.flags & USE_IMMEDIATE16_REL)
272 {
273 disp = (int32_t)(uint16_t)pCpu->param1.parval;
274 }
275 else
276 if (pCpu->param1.flags & USE_IMMEDIATE32_REL)
277 {
278 disp = (int32_t)pCpu->param1.parval;
279 }
280 else
281 {
282 Log(("We don't support far jumps here!! (%08X)\n", pCpu->param1.flags));
283 return 0;
284 }
285#ifdef IN_GC
286 return (RTGCPTR)((uint8_t *)pBranchInstrGC + pCpu->opsize + disp);
287#else
288 return pBranchInstrGC + pCpu->opsize + disp;
289#endif
290}
291
292__BEGIN_DECLS
293CSAMGCDECL(int) CSAMGCCodePageWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
294__END_DECLS
295
296#endif
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