summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/EMInternal.h
blob: b88cf5a630e1cf0c9b4a8803965ab57bbbc9e7c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
/* $Id: EMInternal.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
 * EM - Internal header file.
 */

/*
 * Copyright (C) 2006-2007 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 */

#ifndef ___EMInternal_h
#define ___EMInternal_h

#include <VBox/cdefs.h>
#include <VBox/types.h>
#include <VBox/em.h>
#include <VBox/stam.h>
#include <VBox/patm.h>
#include <VBox/dis.h>
#include <VBox/pdmcritsect.h>
#include <iprt/avl.h>
#include <setjmp.h>

RT_C_DECLS_BEGIN


/** @defgroup grp_em_int       Internal
 * @ingroup grp_em
 * @internal
 * @{
 */

/** The saved state version. */
#define EM_SAVED_STATE_VERSION                          4
#define EM_SAVED_STATE_VERSION_PRE_MWAIT                3
#define EM_SAVED_STATE_VERSION_PRE_SMP                  2


/**
 * MWait state flags.
 */
/* MWait activated. */
#define EMMWAIT_FLAG_ACTIVE             RT_BIT(0)
/* MWait will continue when an interrupt is pending even when IF=0. */
#define EMMWAIT_FLAG_BREAKIRQIF0        RT_BIT(1)
/* Monitor instruction was executed previously. */
#define EMMWAIT_FLAG_MONITOR_ACTIVE     RT_BIT(2)


/**
 * Cli node structure
 */
typedef struct CLISTAT
{
    /** The key is the cli address. */
    AVLGCPTRNODECORE        Core;
#if HC_ARCH_BITS == 32 && !defined(RT_OS_WINDOWS)
    /** Padding. */
    uint32_t                u32Padding;
#endif
    /** Occurrences. */
    STAMCOUNTER             Counter;
} CLISTAT, *PCLISTAT;
#ifdef IN_RING3
AssertCompileMemberAlignment(CLISTAT, Counter, 8);
#endif


/**
 * Excessive EM statistics.
 */
typedef struct EMSTATS
{
    /** GC: Profiling of EMInterpretInstruction(). */
    STAMPROFILE             StatRZEmulate;
    /** HC: Profiling of EMInterpretInstruction(). */
    STAMPROFILE             StatR3Emulate;

    /** @name Interpreter Instruction statistics.
     * @{
     */
    STAMCOUNTER             StatRZInterpretSucceeded;
    STAMCOUNTER             StatR3InterpretSucceeded;

    STAMCOUNTER             StatRZAnd;
    STAMCOUNTER             StatR3And;
    STAMCOUNTER             StatRZCpuId;
    STAMCOUNTER             StatR3CpuId;
    STAMCOUNTER             StatRZDec;
    STAMCOUNTER             StatR3Dec;
    STAMCOUNTER             StatRZHlt;
    STAMCOUNTER             StatR3Hlt;
    STAMCOUNTER             StatRZInc;
    STAMCOUNTER             StatR3Inc;
    STAMCOUNTER             StatRZInvlPg;
    STAMCOUNTER             StatR3InvlPg;
    STAMCOUNTER             StatRZIret;
    STAMCOUNTER             StatR3Iret;
    STAMCOUNTER             StatRZLLdt;
    STAMCOUNTER             StatR3LLdt;
    STAMCOUNTER             StatRZLIdt;
    STAMCOUNTER             StatR3LIdt;
    STAMCOUNTER             StatRZLGdt;
    STAMCOUNTER             StatR3LGdt;
    STAMCOUNTER             StatRZMov;
    STAMCOUNTER             StatR3Mov;
    STAMCOUNTER             StatRZMovCRx;
    STAMCOUNTER             StatR3MovCRx;
    STAMCOUNTER             StatRZMovDRx;
    STAMCOUNTER             StatR3MovDRx;
    STAMCOUNTER             StatRZOr;
    STAMCOUNTER             StatR3Or;
    STAMCOUNTER             StatRZPop;
    STAMCOUNTER             StatR3Pop;
    STAMCOUNTER             StatRZSti;
    STAMCOUNTER             StatR3Sti;
    STAMCOUNTER             StatRZXchg;
    STAMCOUNTER             StatR3Xchg;
    STAMCOUNTER             StatRZXor;
    STAMCOUNTER             StatR3Xor;
    STAMCOUNTER             StatRZMonitor;
    STAMCOUNTER             StatR3Monitor;
    STAMCOUNTER             StatRZMWait;
    STAMCOUNTER             StatR3MWait;
    STAMCOUNTER             StatRZAdd;
    STAMCOUNTER             StatR3Add;
    STAMCOUNTER             StatRZSub;
    STAMCOUNTER             StatR3Sub;
    STAMCOUNTER             StatRZAdc;
    STAMCOUNTER             StatR3Adc;
    STAMCOUNTER             StatRZRdtsc;
    STAMCOUNTER             StatR3Rdtsc;
    STAMCOUNTER             StatRZRdpmc;
    STAMCOUNTER             StatR3Rdpmc;
    STAMCOUNTER             StatRZBtr;
    STAMCOUNTER             StatR3Btr;
    STAMCOUNTER             StatRZBts;
    STAMCOUNTER             StatR3Bts;
    STAMCOUNTER             StatRZBtc;
    STAMCOUNTER             StatR3Btc;
    STAMCOUNTER             StatRZCmpXchg;
    STAMCOUNTER             StatR3CmpXchg;
    STAMCOUNTER             StatRZCmpXchg8b;
    STAMCOUNTER             StatR3CmpXchg8b;
    STAMCOUNTER             StatRZXAdd;
    STAMCOUNTER             StatR3XAdd;
    STAMCOUNTER             StatRZClts;
    STAMCOUNTER             StatR3Clts;
    STAMCOUNTER             StatRZStosWD;
    STAMCOUNTER             StatR3StosWD;
    STAMCOUNTER             StatR3Rdmsr;
    STAMCOUNTER             StatR3Wrmsr;
    STAMCOUNTER             StatRZRdmsr;
    STAMCOUNTER             StatRZWrmsr;
    STAMCOUNTER             StatRZWbInvd;
    STAMCOUNTER             StatR3WbInvd;
    STAMCOUNTER             StatRZLmsw;
    STAMCOUNTER             StatR3Lmsw;
    STAMCOUNTER             StatRZSmsw;
    STAMCOUNTER             StatR3Smsw;

    STAMCOUNTER             StatRZInterpretFailed;
    STAMCOUNTER             StatR3InterpretFailed;

    STAMCOUNTER             StatRZFailedAnd;
    STAMCOUNTER             StatR3FailedAnd;
    STAMCOUNTER             StatRZFailedCpuId;
    STAMCOUNTER             StatR3FailedCpuId;
    STAMCOUNTER             StatRZFailedDec;
    STAMCOUNTER             StatR3FailedDec;
    STAMCOUNTER             StatRZFailedHlt;
    STAMCOUNTER             StatR3FailedHlt;
    STAMCOUNTER             StatRZFailedInc;
    STAMCOUNTER             StatR3FailedInc;
    STAMCOUNTER             StatRZFailedInvlPg;
    STAMCOUNTER             StatR3FailedInvlPg;
    STAMCOUNTER             StatRZFailedIret;
    STAMCOUNTER             StatR3FailedIret;
    STAMCOUNTER             StatRZFailedLLdt;
    STAMCOUNTER             StatR3FailedLLdt;
    STAMCOUNTER             StatRZFailedLGdt;
    STAMCOUNTER             StatR3FailedLGdt;
    STAMCOUNTER             StatRZFailedLIdt;
    STAMCOUNTER             StatR3FailedLIdt;
    STAMCOUNTER             StatRZFailedMisc;
    STAMCOUNTER             StatR3FailedMisc;
    STAMCOUNTER             StatRZFailedMov;
    STAMCOUNTER             StatR3FailedMov;
    STAMCOUNTER             StatRZFailedMovCRx;
    STAMCOUNTER             StatR3FailedMovCRx;
    STAMCOUNTER             StatRZFailedMovDRx;
    STAMCOUNTER             StatR3FailedMovDRx;
    STAMCOUNTER             StatRZFailedOr;
    STAMCOUNTER             StatR3FailedOr;
    STAMCOUNTER             StatRZFailedPop;
    STAMCOUNTER             StatR3FailedPop;
    STAMCOUNTER             StatRZFailedSti;
    STAMCOUNTER             StatR3FailedSti;
    STAMCOUNTER             StatRZFailedXchg;
    STAMCOUNTER             StatR3FailedXchg;
    STAMCOUNTER             StatRZFailedXor;
    STAMCOUNTER             StatR3FailedXor;
    STAMCOUNTER             StatRZFailedMonitor;
    STAMCOUNTER             StatR3FailedMonitor;
    STAMCOUNTER             StatRZFailedMWait;
    STAMCOUNTER             StatR3FailedMWait;
    STAMCOUNTER             StatR3FailedRdmsr;
    STAMCOUNTER             StatR3FailedWrmsr;
    STAMCOUNTER             StatRZFailedRdmsr;
    STAMCOUNTER             StatRZFailedWrmsr;
    STAMCOUNTER             StatRZFailedLmsw;
    STAMCOUNTER             StatR3FailedLmsw;
    STAMCOUNTER             StatRZFailedSmsw;
    STAMCOUNTER             StatR3FailedSmsw;

    STAMCOUNTER             StatRZFailedAdd;
    STAMCOUNTER             StatR3FailedAdd;
    STAMCOUNTER             StatRZFailedAdc;
    STAMCOUNTER             StatR3FailedAdc;
    STAMCOUNTER             StatRZFailedBtr;
    STAMCOUNTER             StatR3FailedBtr;
    STAMCOUNTER             StatRZFailedBts;
    STAMCOUNTER             StatR3FailedBts;
    STAMCOUNTER             StatRZFailedBtc;
    STAMCOUNTER             StatR3FailedBtc;
    STAMCOUNTER             StatRZFailedCli;
    STAMCOUNTER             StatR3FailedCli;
    STAMCOUNTER             StatRZFailedCmpXchg;
    STAMCOUNTER             StatR3FailedCmpXchg;
    STAMCOUNTER             StatRZFailedCmpXchg8b;
    STAMCOUNTER             StatR3FailedCmpXchg8b;
    STAMCOUNTER             StatRZFailedXAdd;
    STAMCOUNTER             StatR3FailedXAdd;
    STAMCOUNTER             StatR3FailedMovNTPS;
    STAMCOUNTER             StatRZFailedMovNTPS;
    STAMCOUNTER             StatRZFailedStosWD;
    STAMCOUNTER             StatR3FailedStosWD;
    STAMCOUNTER             StatRZFailedSub;
    STAMCOUNTER             StatR3FailedSub;
    STAMCOUNTER             StatRZFailedWbInvd;
    STAMCOUNTER             StatR3FailedWbInvd;
    STAMCOUNTER             StatRZFailedRdtsc;
    STAMCOUNTER             StatR3FailedRdtsc;
    STAMCOUNTER             StatRZFailedRdpmc;
    STAMCOUNTER             StatR3FailedRdpmc;
    STAMCOUNTER             StatRZFailedClts;
    STAMCOUNTER             StatR3FailedClts;

    STAMCOUNTER             StatRZFailedUserMode;
    STAMCOUNTER             StatR3FailedUserMode;
    STAMCOUNTER             StatRZFailedPrefix;
    STAMCOUNTER             StatR3FailedPrefix;
    /** @} */

    /** @name Privileged Instructions Ending Up In HC.
     * @{ */
    STAMCOUNTER             StatCli;
    STAMCOUNTER             StatSti;
    STAMCOUNTER             StatIn;
    STAMCOUNTER             StatIoRestarted;
    STAMCOUNTER             StatOut;
    STAMCOUNTER             StatInvlpg;
    STAMCOUNTER             StatHlt;
    STAMCOUNTER             StatMovReadCR[USE_REG_CR4 + 1];
    STAMCOUNTER             StatMovWriteCR[USE_REG_CR4 + 1];
    STAMCOUNTER             StatMovDRx;
    STAMCOUNTER             StatIret;
    STAMCOUNTER             StatMovLgdt;
    STAMCOUNTER             StatMovLldt;
    STAMCOUNTER             StatMovLidt;
    STAMCOUNTER             StatMisc;
    STAMCOUNTER             StatSysEnter;
    STAMCOUNTER             StatSysExit;
    STAMCOUNTER             StatSysCall;
    STAMCOUNTER             StatSysRet;
    /** @} */

} EMSTATS;
/** Pointer to the excessive EM statistics. */
typedef EMSTATS *PEMSTATS;


/**
 * Converts a EM pointer into a VM pointer.
 * @returns Pointer to the VM structure the EM is part of.
 * @param   pEM   Pointer to EM instance data.
 */
#define EM2VM(pEM)  ( (PVM)((char*)pEM - pEM->offVM) )

/**
 * EM VM Instance data.
 * Changes to this must checked against the padding of the cfgm union in VM!
 */
typedef struct EM
{
    /** Offset to the VM structure.
     * See EM2VM(). */
    RTUINT                  offVM;

    /** Id of the VCPU that last executed code in the recompiler. */
    VMCPUID                 idLastRemCpu;

    /** REM critical section.
     * This protects recompiler usage
     */
    PDMCRITSECT             CritSectREM;
} EM;
/** Pointer to EM VM instance data. */
typedef EM *PEM;


/**
 * EM VMCPU Instance data.
 */
typedef struct EMCPU
{
    /** Offset to the VM structure.
     * See EMCPU2VM(). */
    RTUINT                  offVMCPU;

    /** Execution Manager State. */
    EMSTATE volatile        enmState;

    /** Previous Execution Manager State. */
    EMSTATE                 enmPrevState;

    /** Force raw-mode execution.
     * This is used to prevent REM from trying to execute patch code.
     * The flag is cleared upon entering emR3RawExecute() and updated in certain return paths. */
    bool                    fForceRAW;

    uint8_t                 u8Padding[3];

    /** Inhibit interrupts for this instruction. Valid only when VM_FF_INHIBIT_INTERRUPTS is set. */
    RTGCUINTPTR             GCPtrInhibitInterrupts;

    /** Pointer to the PATM status structure. (R3 Ptr) */
    R3PTRTYPE(PPATMGCSTATE) pPatmGCState;

    /** Pointer to the guest CPUM state. (R3 Ptr) */
    R3PTRTYPE(PCPUMCTX)     pCtx;

#if GC_ARCH_BITS == 64
    RTGCPTR                 aPadding1;
#endif

    /* MWait halt state. */
    struct
    {
        uint32_t            fWait;          /* type of mwait; see EMMWAIT_FLAG_* */
        uint32_t            a32Padding[1];
        RTGCPTR             uMWaitEAX;      /* mwait hints */
        RTGCPTR             uMWaitECX;      /* mwait extensions */
        RTGCPTR             uMonitorEAX;    /* monitored address. */
        RTGCPTR             uMonitorECX;    /* monitor extension. */
        RTGCPTR             uMonitorEDX;    /* monitor hint. */
    } mwait;

    union
    {
        /** Padding used in the other rings.
         * This must be larger than jmp_buf on any supported platform. */
        char                achPaddingFatalLongJump[HC_ARCH_BITS == 32 ? 176 : 256];
#ifdef IN_RING3
        /** Long buffer jump for fatal VM errors.
         * It will jump to before the outer EM loop is entered. */
        jmp_buf             FatalLongJump;
#endif
    } u;

    /** For saving stack space, the disassembler state is allocated here instead of
     * on the stack.
     * @note The DISCPUSTATE structure is not R3/R0/RZ clean!  */
    union
    {
        /** The disassembler scratch space. */
        DISCPUSTATE         DisState;
        /** Padding. */
        uint8_t             abDisStatePadding[DISCPUSTATE_PADDING_SIZE];
    };

    /** @name Execution profiling.
     * @{ */
    STAMPROFILE             StatForcedActions;
    STAMPROFILE             StatHalted;
    STAMPROFILEADV          StatHwAccEntry;
    STAMPROFILE             StatHwAccExec;
    STAMPROFILE             StatREMEmu;
    STAMPROFILE             StatREMExec;
    STAMPROFILE             StatREMSync;
    STAMPROFILEADV          StatREMTotal;
    STAMPROFILE             StatRAWExec;
    STAMPROFILEADV          StatRAWEntry;
    STAMPROFILEADV          StatRAWTail;
    STAMPROFILEADV          StatRAWTotal;
    STAMPROFILEADV          StatTotal;
    /** @} */

    /** R3: Profiling of emR3RawExecuteIOInstruction. */
    STAMPROFILE             StatIOEmu;
    /** R3: Profiling of emR3RawPrivileged. */
    STAMPROFILE             StatPrivEmu;
    /** R3: Number of time emR3HwAccExecute is called. */
    STAMCOUNTER             StatHwAccExecuteEntry;

    /** More statistics (R3). */
    R3PTRTYPE(PEMSTATS)     pStatsR3;
    /** More statistics (R0). */
    R0PTRTYPE(PEMSTATS)     pStatsR0;
    /** More statistics (RC). */
    RCPTRTYPE(PEMSTATS)     pStatsRC;
#if HC_ARCH_BITS == 64
    RTRCPTR                 padding0;
#endif

    /** Tree for keeping track of cli occurances (debug only). */
    R3PTRTYPE(PAVLGCPTRNODECORE) pCliStatTree;
    STAMCOUNTER             StatTotalClis;
#if 0
    /** 64-bit Visual C++ rounds the struct size up to 16 byte. */
    uint64_t                padding1;
#endif
} EMCPU;
/** Pointer to EM VM instance data. */
typedef EMCPU *PEMCPU;

/** @} */


int     emR3HwAccExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
int     emR3RawExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
int     emR3RawHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
int     emR3HwaccmHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
int     emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc);
int     emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, int rc);
int     emR3RawUpdateForceFlag(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
int     emR3RawResumeHyper(PVM pVM, PVMCPU pVCpu);
int     emR3RawStep(PVM pVM, PVMCPU pVCpu);
int     emR3SingleStepExecRem(PVM pVM, PVMCPU pVCpu, uint32_t cIterations);

RT_C_DECLS_END

#endif