VirtualBox

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

Last change on this file since 77807 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

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