VirtualBox

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

Last change on this file since 515 was 347, checked in by vboxsync, 18 years ago

Rewrote and simplified interrupt handler patching.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette