VirtualBox

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

Last change on this file since 30060 was 28800, checked in by vboxsync, 14 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

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