VirtualBox

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

Last change on this file since 74795 was 69474, checked in by vboxsync, 7 years ago

*: scm updates - header files should have 'svn:keywords=Id Revision' too (doesn't mean they have to use them).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.6 KB
Line 
1/* $Id: CSAMInternal.h 69474 2017-10-28 13:12:06Z vboxsync $ */
2/** @file
3 * CSAM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2017 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 CSAM_SAVED_STATE_VERSION_PUT_STRUCT
42#define CSAM_SAVED_STATE_VERSION_PUT_STRUCT 15
43#define CSAM_SAVED_STATE_VERSION_PUT_MEM 14
44
45#define CSAM_PGDIRBMP_CHUNKS 1024
46
47#define CSAM_PAGE_BITMAP_SIZE (PAGE_SIZE/(sizeof(uint8_t)*8))
48
49/* Maximum nr of dirty page that are cached. */
50#define CSAM_MAX_DIRTY_PAGES 32
51
52/* Maximum number of cached addresses of dangerous instructions that have been scanned before. */
53#define CSAM_MAX_DANGR_INSTR 16 /* power of two! */
54#define CSAM_MAX_DANGR_INSTR_MASK (CSAM_MAX_DANGR_INSTR-1)
55
56/* Maximum number of possible dangerous code pages that we'll flush after a world switch */
57#define CSAM_MAX_CODE_PAGES_FLUSH 32
58
59#define CSAM_MAX_CALLEXIT_RET 16
60
61/* copy from PATMInternal.h */
62#define SIZEOF_NEARJUMP32 5 //opcode byte + 4 byte relative offset
63
64typedef struct
65{
66 RTRCPTR pInstrAfterRetGC[CSAM_MAX_CALLEXIT_RET];
67 uint32_t cInstrAfterRet;
68} CSAMCALLEXITREC, *PCSAMCALLEXITREC;
69
70typedef struct
71{
72 R3PTRTYPE(uint8_t *) pPageLocStartHC;
73 R3PTRTYPE(uint8_t *) pPageLocEndHC;
74 RCPTRTYPE(uint8_t *) pGuestLoc;
75 uint32_t depth; //call/jump depth
76
77 PCSAMCALLEXITREC pCallExitRec;
78
79 PGMPAGEMAPLOCK Lock;
80} CSAMP2GLOOKUPREC, *PCSAMP2GLOOKUPREC;
81
82typedef struct
83{
84 RTRCPTR 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 RTRCPTR 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#if HC_ARCH_BITS == 64
147 RTINT Alignment0; /**< Align pPageTree correctly. */
148#endif
149
150 R3PTRTYPE(PAVLPVNODECORE) pPageTree;
151
152 /* Array to store previously scanned dangerous instructions, so we don't need to
153 * switch back to ring 3 each time we encounter them in GC.
154 */
155 RTRCPTR aDangerousInstr[CSAM_MAX_DANGR_INSTR];
156 uint32_t cDangerousInstr;
157 uint32_t iDangerousInstr;
158
159 RCPTRTYPE(RTRCPTR *) pPDBitmapGC;
160 RCPTRTYPE(RTHCPTR *) pPDHCBitmapGC;
161 R3PTRTYPE(uint8_t **) pPDBitmapHC;
162 R3PTRTYPE(RTRCPTR *) pPDGCBitmapHC;
163
164 /* Temporary storage during load/save state */
165 struct
166 {
167 R3PTRTYPE(PSSMHANDLE) pSSM;
168 uint32_t cPageRecords;
169 uint32_t cPatchPageRecords;
170 } savedstate;
171
172 /* To keep track of dirty pages */
173 uint32_t cDirtyPages;
174 RTRCPTR pvDirtyBasePage[CSAM_MAX_DIRTY_PAGES];
175 RTRCPTR pvDirtyFaultPage[CSAM_MAX_DIRTY_PAGES];
176
177 /* To keep track of possible code pages */
178 uint32_t cPossibleCodePages;
179 RTRCPTR pvPossibleCodePage[CSAM_MAX_CODE_PAGES_FLUSH];
180
181 /* call addresses reported by the recompiler */
182 RTRCPTR pvCallInstruction[16];
183 uint32_t iCallInstruction;
184
185 /** Code page write access handler type. */
186 PGMVIRTHANDLERTYPE hCodePageWriteType;
187 /** Code page write & invalidation access handler type. */
188 PGMVIRTHANDLERTYPE hCodePageWriteAndInvPgType;
189
190 /* Set when scanning has started. */
191 bool fScanningStarted;
192
193 /* Set when the IDT gates have been checked for the first time. */
194 bool fGatesChecked;
195 bool Alignment1[HC_ARCH_BITS == 32 ? 6 : 2]; /**< Align the stats on an 8-byte boundary. */
196
197 STAMCOUNTER StatNrTraps;
198 STAMCOUNTER StatNrPages;
199 STAMCOUNTER StatNrPagesInv;
200 STAMCOUNTER StatNrRemovedPages;
201 STAMCOUNTER StatNrPatchPages;
202 STAMCOUNTER StatNrPageNPHC;
203 STAMCOUNTER StatNrPageNPGC;
204 STAMCOUNTER StatNrFlushes;
205 STAMCOUNTER StatNrFlushesSkipped;
206 STAMCOUNTER StatNrKnownPagesHC;
207 STAMCOUNTER StatNrKnownPagesGC;
208 STAMCOUNTER StatNrInstr;
209 STAMCOUNTER StatNrBytesRead;
210 STAMCOUNTER StatNrOpcodeRead;
211 STAMPROFILE StatTime;
212 STAMPROFILE StatTimeCheckAddr;
213 STAMPROFILE StatTimeAddrConv;
214 STAMPROFILE StatTimeFlushPage;
215 STAMPROFILE StatTimeDisasm;
216 STAMPROFILE StatFlushDirtyPages;
217 STAMPROFILE StatCheckGates;
218 STAMCOUNTER StatCodePageModified;
219 STAMCOUNTER StatDangerousWrite;
220
221 STAMCOUNTER StatInstrCacheHit;
222 STAMCOUNTER StatInstrCacheMiss;
223
224 STAMCOUNTER StatPagePATM;
225 STAMCOUNTER StatPageCSAM;
226 STAMCOUNTER StatPageREM;
227 STAMCOUNTER StatNrUserPages;
228 STAMCOUNTER StatPageMonitor;
229 STAMCOUNTER StatPageRemoveREMFlush;
230
231 STAMCOUNTER StatBitmapAlloc;
232
233 STAMCOUNTER StatScanNextFunction;
234 STAMCOUNTER StatScanNextFunctionFailed;
235} CSAM, *PCSAM;
236
237/**
238 * Call for analyzing the instructions following the privileged instr. for compliance with our heuristics
239 *
240 * @returns VBox status code.
241 * @param pVM The cross context VM structure.
242 * @param pCpu CPU disassembly state
243 * @param pInstrHC Guest context pointer to privileged instruction
244 * @param pCurInstrGC Guest context pointer to current instruction
245 * @param pUserData User pointer
246 *
247 */
248typedef int (VBOXCALL *PFN_CSAMR3ANALYSE)(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_t *) pInstrGC, RCPTRTYPE(uint8_t *) pCurInstrGC, PCSAMP2GLOOKUPREC pCacheRec, void *pUserData);
249
250/**
251 * Calculate the branch destination
252 *
253 * @returns branch destination or 0 if failed
254 * @param pCpu Disassembly state of instruction.
255 * @param pBranchInstrGC GC pointer of branch instruction
256 */
257inline RTRCPTR CSAMResolveBranch(PDISCPUSTATE pCpu, RTRCPTR pBranchInstrGC)
258{
259 uint32_t disp;
260 if (pCpu->Param1.fUse & DISUSE_IMMEDIATE8_REL)
261 {
262 disp = (int32_t)(char)pCpu->Param1.uValue;
263 }
264 else
265 if (pCpu->Param1.fUse & DISUSE_IMMEDIATE16_REL)
266 {
267 disp = (int32_t)(uint16_t)pCpu->Param1.uValue;
268 }
269 else
270 if (pCpu->Param1.fUse & DISUSE_IMMEDIATE32_REL)
271 {
272 disp = (int32_t)pCpu->Param1.uValue;
273 }
274 else
275 {
276 Log(("We don't support far jumps here!! (%08X)\n", pCpu->Param1.fUse));
277 return 0;
278 }
279#ifdef IN_RC
280 return (RTRCPTR)((uint8_t *)pBranchInstrGC + pCpu->cbInstr + disp);
281#else
282 return pBranchInstrGC + pCpu->cbInstr + disp;
283#endif
284}
285
286PGM_ALL_CB2_PROTO(FNPGMVIRTHANDLER) csamCodePageWriteHandler;
287RT_C_DECLS_BEGIN
288DECLEXPORT(FNPGMRCVIRTPFHANDLER) csamRCCodePageWritePfHandler;
289RT_C_DECLS_END
290
291#endif
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use