VirtualBox

source: vbox/trunk/src/VBox/VMM/include/CSAMInternal.h@ 55889

Last change on this file since 55889 was 55889, checked in by vboxsync, 9 years ago

VMM: Split up virtual handlers just like the physical ones, such that the kind+callbacks are stored seprately from the actual handler registration. This should hopefully save a byte or two when adding more callbacks. Implemented the pvUser for ring-3 callbacks.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.5 KB
Line 
1/* $Id: CSAMInternal.h 55889 2015-05-17 18:01:37Z vboxsync $ */
2/** @file
3 * CSAM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2014 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/vmm/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_SAVED_STATE_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
77 PGMPAGEMAPLOCK Lock;
78} CSAMP2GLOOKUPREC, *PCSAMP2GLOOKUPREC;
79
80typedef struct
81{
82 RTRCPTR pPageGC;
83 RTGCPHYS GCPhys;
84 uint64_t fFlags;
85 uint32_t uSize;
86
87 uint8_t *pBitmap;
88
89 bool fCode32;
90 bool fMonitorActive;
91 bool fMonitorInvalidation;
92
93 CSAMTAG enmTag;
94
95 uint64_t u64Hash;
96} CSAMPAGE, *PCSAMPAGE;
97
98typedef struct
99{
100 // GC Patch pointer
101 RTRCPTR pInstrGC;
102
103 // Disassembly state for original instruction
104 DISCPUSTATE cpu;
105
106 uint32_t uState;
107
108 PCSAMPAGE pPage;
109} CSAMPATCH, *PCSAMPATCH;
110
111/**
112 * Lookup record for CSAM pages
113 */
114typedef struct CSAMPAGEREC
115{
116 /** The key is a GC virtual address. */
117 AVLPVNODECORE Core;
118 CSAMPAGE page;
119
120} CSAMPAGEREC, *PCSAMPAGEREC;
121
122/**
123 * Lookup record for patches
124 */
125typedef struct CSAMPATCHREC
126{
127 /** The key is a GC virtual address. */
128 AVLPVNODECORE Core;
129 CSAMPATCH patch;
130
131} CSAMPATCHREC, *PCSAMPATCHREC;
132
133
134/**
135 * CSAM VM Instance data.
136 * Changes to this must checked against the padding of the CSAM union in VM!
137 * @note change SSM version when changing it!!
138 */
139typedef struct CSAM
140{
141 /** Offset to the VM structure.
142 * See CSAM2VM(). */
143 RTINT offVM;
144#if HC_ARCH_BITS == 64
145 RTINT Alignment0; /**< Align pPageTree correctly. */
146#endif
147
148 R3PTRTYPE(PAVLPVNODECORE) pPageTree;
149
150 /* Array to store previously scanned dangerous instructions, so we don't need to
151 * switch back to ring 3 each time we encounter them in GC.
152 */
153 RTRCPTR aDangerousInstr[CSAM_MAX_DANGR_INSTR];
154 uint32_t cDangerousInstr;
155 uint32_t iDangerousInstr;
156
157 RCPTRTYPE(RTRCPTR *) pPDBitmapGC;
158 RCPTRTYPE(RTHCPTR *) pPDHCBitmapGC;
159 R3PTRTYPE(uint8_t **) pPDBitmapHC;
160 R3PTRTYPE(RTRCPTR *) pPDGCBitmapHC;
161
162 /* Temporary storage during load/save state */
163 struct
164 {
165 R3PTRTYPE(PSSMHANDLE) pSSM;
166 uint32_t cPageRecords;
167 uint32_t cPatchPageRecords;
168 } savedstate;
169
170 /* To keep track of dirty pages */
171 uint32_t cDirtyPages;
172 RTRCPTR pvDirtyBasePage[CSAM_MAX_DIRTY_PAGES];
173 RTRCPTR pvDirtyFaultPage[CSAM_MAX_DIRTY_PAGES];
174
175 /* To keep track of possible code pages */
176 uint32_t cPossibleCodePages;
177 RTRCPTR pvPossibleCodePage[CSAM_MAX_CODE_PAGES_FLUSH];
178
179 /* call addresses reported by the recompiler */
180 RTRCPTR pvCallInstruction[16];
181 uint32_t iCallInstruction;
182
183 /** Code page write access handler type. */
184 PGMVIRTHANDLERTYPE hCodePageWriteType;
185 /** Code page write & invalidation access handler type. */
186 PGMVIRTHANDLERTYPE hCodePageWriteAndInvPgType;
187
188 /* Set when scanning has started. */
189 bool fScanningStarted;
190
191 /* Set when the IDT gates have been checked for the first time. */
192 bool fGatesChecked;
193 bool Alignment1[HC_ARCH_BITS == 32 ? 6 : 2]; /**< Align the stats on an 8-byte boundary. */
194
195 STAMCOUNTER StatNrTraps;
196 STAMCOUNTER StatNrPages;
197 STAMCOUNTER StatNrPagesInv;
198 STAMCOUNTER StatNrRemovedPages;
199 STAMCOUNTER StatNrPatchPages;
200 STAMCOUNTER StatNrPageNPHC;
201 STAMCOUNTER StatNrPageNPGC;
202 STAMCOUNTER StatNrFlushes;
203 STAMCOUNTER StatNrFlushesSkipped;
204 STAMCOUNTER StatNrKnownPagesHC;
205 STAMCOUNTER StatNrKnownPagesGC;
206 STAMCOUNTER StatNrInstr;
207 STAMCOUNTER StatNrBytesRead;
208 STAMCOUNTER StatNrOpcodeRead;
209 STAMPROFILE StatTime;
210 STAMPROFILE StatTimeCheckAddr;
211 STAMPROFILE StatTimeAddrConv;
212 STAMPROFILE StatTimeFlushPage;
213 STAMPROFILE StatTimeDisasm;
214 STAMPROFILE StatFlushDirtyPages;
215 STAMPROFILE StatCheckGates;
216 STAMCOUNTER StatCodePageModified;
217 STAMCOUNTER StatDangerousWrite;
218
219 STAMCOUNTER StatInstrCacheHit;
220 STAMCOUNTER StatInstrCacheMiss;
221
222 STAMCOUNTER StatPagePATM;
223 STAMCOUNTER StatPageCSAM;
224 STAMCOUNTER StatPageREM;
225 STAMCOUNTER StatNrUserPages;
226 STAMCOUNTER StatPageMonitor;
227 STAMCOUNTER StatPageRemoveREMFlush;
228
229 STAMCOUNTER StatBitmapAlloc;
230
231 STAMCOUNTER StatScanNextFunction;
232 STAMCOUNTER StatScanNextFunctionFailed;
233} CSAM, *PCSAM;
234
235/**
236 * Call for analyzing the instructions following the privileged instr. for compliance with our heuristics
237 *
238 * @returns VBox status code.
239 * @param pVM Pointer to the VM.
240 * @param pCpu CPU disassembly state
241 * @param pInstrHC Guest context pointer to privileged instruction
242 * @param pCurInstrGC Guest context pointer to current instruction
243 * @param pUserData User pointer
244 *
245 */
246typedef int (VBOXCALL *PFN_CSAMR3ANALYSE)(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_t *) pInstrGC, RCPTRTYPE(uint8_t *) pCurInstrGC, PCSAMP2GLOOKUPREC pCacheRec, void *pUserData);
247
248/**
249 * Calculate the branch destination
250 *
251 * @returns branch destination or 0 if failed
252 * @param pCpu Disassembly state of instruction.
253 * @param pBranchInstrGC GC pointer of branch instruction
254 */
255inline RTRCPTR CSAMResolveBranch(PDISCPUSTATE pCpu, RTRCPTR pBranchInstrGC)
256{
257 uint32_t disp;
258 if (pCpu->Param1.fUse & DISUSE_IMMEDIATE8_REL)
259 {
260 disp = (int32_t)(char)pCpu->Param1.uValue;
261 }
262 else
263 if (pCpu->Param1.fUse & DISUSE_IMMEDIATE16_REL)
264 {
265 disp = (int32_t)(uint16_t)pCpu->Param1.uValue;
266 }
267 else
268 if (pCpu->Param1.fUse & DISUSE_IMMEDIATE32_REL)
269 {
270 disp = (int32_t)pCpu->Param1.uValue;
271 }
272 else
273 {
274 Log(("We don't support far jumps here!! (%08X)\n", pCpu->Param1.fUse));
275 return 0;
276 }
277#ifdef IN_RC
278 return (RTRCPTR)((uint8_t *)pBranchInstrGC + pCpu->cbInstr + disp);
279#else
280 return pBranchInstrGC + pCpu->cbInstr + disp;
281#endif
282}
283
284RT_C_DECLS_BEGIN
285VMMRCDECL(int) CSAMGCCodePageWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
286RT_C_DECLS_END
287
288#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