VirtualBox

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

Last change on this file since 2870 was 1860, checked in by vboxsync, 18 years ago

put back 64 bits fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.9 KB
Line 
1/* $Id: CSAMInternal.h 1860 2007-04-02 14:09:10Z vboxsync $ */
2/** @file
3 * CSAM - Internal header file.
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 __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