VirtualBox

source: vbox/trunk/src/VBox/VMM/include/VMMInternal.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: 28.9 KB
Line 
1/* $Id: VMMInternal.h 76585 2019-01-01 06:31:29Z vboxsync $ */
2/** @file
3 * VMM - 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_VMMInternal_h
19#define VMM_INCLUDED_SRC_include_VMMInternal_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <VBox/cdefs.h>
25#include <VBox/sup.h>
26#include <VBox/vmm/stam.h>
27#include <VBox/vmm/vmm.h>
28#include <VBox/log.h>
29#include <iprt/critsect.h>
30
31#if !defined(IN_VMM_R3) && !defined(IN_VMM_R0) && !defined(IN_VMM_RC)
32# error "Not in VMM! This is an internal header!"
33#endif
34#if defined(RT_OS_DARWIN) && HC_ARCH_BITS == 32
35# error "32-bit darwin is no longer supported. Go back to 4.3 or earlier!"
36#endif
37
38
39
40/** @defgroup grp_vmm_int Internals
41 * @ingroup grp_vmm
42 * @internal
43 * @{
44 */
45
46/** @def VBOX_WITH_RC_RELEASE_LOGGING
47 * Enables RC release logging. */
48#define VBOX_WITH_RC_RELEASE_LOGGING
49
50/** @def VBOX_WITH_R0_LOGGING
51 * Enables Ring-0 logging (non-release).
52 *
53 * Ring-0 logging isn't 100% safe yet (thread id reuse / process exit cleanup),
54 * so you have to sign up here by adding your defined(DEBUG_<userid>) to the
55 * \#if, or by adding VBOX_WITH_R0_LOGGING to your LocalConfig.kmk.
56 */
57#if defined(DEBUG_sandervl) || defined(DEBUG_frank) || defined(DEBUG_ramshankar) || defined(DOXYGEN_RUNNING)
58# define VBOX_WITH_R0_LOGGING
59#endif
60
61/** @def VBOX_STRICT_VMM_STACK
62 * Enables VMM stack guard pages to catch stack over- and underruns. */
63#if defined(VBOX_STRICT) || defined(DOXYGEN_RUNNING)
64# define VBOX_STRICT_VMM_STACK
65#endif
66
67
68/**
69 * Converts a VMM pointer into a VM pointer.
70 * @returns Pointer to the VM structure the VMM is part of.
71 * @param pVMM Pointer to VMM instance data.
72 */
73#define VMM2VM(pVMM) ( (PVM)((char*)pVMM - pVMM->offVM) )
74
75
76/**
77 * Switcher function, HC to RC.
78 *
79 * @param pVM The cross context VM structure.
80 * @returns Return code indicating the action to take.
81 */
82typedef DECLASMTYPE(int) FNVMMSWITCHERHC(PVM pVM);
83/** Pointer to switcher function. */
84typedef FNVMMSWITCHERHC *PFNVMMSWITCHERHC;
85
86/**
87 * Switcher function, RC to HC.
88 *
89 * @param rc VBox status code.
90 */
91typedef DECLASMTYPE(void) FNVMMSWITCHERRC(int rc);
92/** Pointer to switcher function. */
93typedef FNVMMSWITCHERRC *PFNVMMSWITCHERRC;
94
95
96/**
97 * The ring-0 logger instance wrapper.
98 *
99 * We need to be able to find the VM handle from the logger instance, so we wrap
100 * it in this structure.
101 */
102typedef struct VMMR0LOGGER
103{
104 /** Pointer to Pointer to the VM. */
105 R0PTRTYPE(PVM) pVM;
106 /** Size of the allocated logger instance (Logger). */
107 uint32_t cbLogger;
108 /** Flag indicating whether we've create the logger Ring-0 instance yet. */
109 bool fCreated;
110 /** Flag indicating whether we've disabled flushing (world switch) or not. */
111 bool fFlushingDisabled;
112 /** Flag indicating whether we've registered the instance already. */
113 bool fRegistered;
114 bool a8Alignment;
115 /** The CPU ID. */
116 VMCPUID idCpu;
117#if HC_ARCH_BITS == 64
118 uint32_t u32Alignment;
119#endif
120 /** The ring-0 logger instance. This extends beyond the size. */
121 RTLOGGER Logger;
122} VMMR0LOGGER;
123/** Pointer to a ring-0 logger instance wrapper. */
124typedef VMMR0LOGGER *PVMMR0LOGGER;
125
126
127/**
128 * Jump buffer for the setjmp/longjmp like constructs used to
129 * quickly 'call' back into Ring-3.
130 */
131typedef struct VMMR0JMPBUF
132{
133 /** Traditional jmp_buf stuff
134 * @{ */
135#if HC_ARCH_BITS == 32
136 uint32_t ebx;
137 uint32_t esi;
138 uint32_t edi;
139 uint32_t ebp;
140 uint32_t esp;
141 uint32_t eip;
142 uint32_t eflags;
143#endif
144#if HC_ARCH_BITS == 64
145 uint64_t rbx;
146# ifdef RT_OS_WINDOWS
147 uint64_t rsi;
148 uint64_t rdi;
149# endif
150 uint64_t rbp;
151 uint64_t r12;
152 uint64_t r13;
153 uint64_t r14;
154 uint64_t r15;
155 uint64_t rsp;
156 uint64_t rip;
157# ifdef RT_OS_WINDOWS
158 uint128_t xmm6;
159 uint128_t xmm7;
160 uint128_t xmm8;
161 uint128_t xmm9;
162 uint128_t xmm10;
163 uint128_t xmm11;
164 uint128_t xmm12;
165 uint128_t xmm13;
166 uint128_t xmm14;
167 uint128_t xmm15;
168# endif
169 uint64_t rflags;
170#endif
171 /** @} */
172
173 /** Flag that indicates that we've done a ring-3 call. */
174 bool fInRing3Call;
175 /** The number of bytes we've saved. */
176 uint32_t cbSavedStack;
177 /** Pointer to the buffer used to save the stack.
178 * This is assumed to be 8KB. */
179 RTR0PTR pvSavedStack;
180 /** Esp we we match against esp on resume to make sure the stack wasn't relocated. */
181 RTHCUINTREG SpCheck;
182 /** The esp we should resume execution with after the restore. */
183 RTHCUINTREG SpResume;
184 /** ESP/RSP at the time of the jump to ring 3. */
185 RTHCUINTREG SavedEsp;
186 /** EBP/RBP at the time of the jump to ring 3. */
187 RTHCUINTREG SavedEbp;
188 /** EIP/RIP within vmmR0CallRing3LongJmp for assisting unwinding. */
189 RTHCUINTREG SavedEipForUnwind;
190 /** Unwind: The vmmR0CallRing3SetJmp return address value. */
191 RTHCUINTREG UnwindRetPcValue;
192 /** Unwind: The vmmR0CallRing3SetJmp return address stack location. */
193 RTHCUINTREG UnwindRetPcLocation;
194#if HC_ARCH_BITS == 32
195 /** Alignment padding. */
196 uint32_t uPadding;
197#endif
198
199 /** Stats: Max amount of stack used. */
200 uint32_t cbUsedMax;
201 /** Stats: Average stack usage. (Avg = cbUsedTotal / cUsedTotal) */
202 uint32_t cbUsedAvg;
203 /** Stats: Total amount of stack used. */
204 uint64_t cbUsedTotal;
205 /** Stats: Number of stack usages. */
206 uint64_t cUsedTotal;
207} VMMR0JMPBUF;
208/** Pointer to a ring-0 jump buffer. */
209typedef VMMR0JMPBUF *PVMMR0JMPBUF;
210
211
212/**
213 * VMM Data (part of VM)
214 */
215typedef struct VMM
216{
217 /** Offset to the VM structure.
218 * See VMM2VM(). */
219 RTINT offVM;
220
221 /** @name World Switcher and Related
222 * @{
223 */
224 /** Size of the core code. */
225 RTUINT cbCoreCode;
226 /** Physical address of core code. */
227 RTHCPHYS HCPhysCoreCode;
228 /** Pointer to core code ring-3 mapping - contiguous memory.
229 * At present this only means the context switcher code. */
230 RTR3PTR pvCoreCodeR3;
231 /** Pointer to core code ring-0 mapping - contiguous memory.
232 * At present this only means the context switcher code. */
233 RTR0PTR pvCoreCodeR0;
234 /** Pointer to core code guest context mapping. */
235 RTRCPTR pvCoreCodeRC;
236 RTRCPTR pRCPadding0; /**< Alignment padding. */
237#ifdef VBOX_WITH_NMI
238 /** The guest context address of the APIC (host) mapping. */
239 RTRCPTR GCPtrApicBase;
240 RTRCPTR pRCPadding1; /**< Alignment padding. */
241#endif
242 /** The current switcher.
243 * This will be set before the VMM is fully initialized. */
244 VMMSWITCHER enmSwitcher;
245 /** Array of offsets to the different switchers within the core code. */
246 uint32_t aoffSwitchers[VMMSWITCHER_MAX];
247 uint32_t u32Padding2; /**< Alignment padding. */
248
249 /** Resume Guest Execution. See CPUMGCResumeGuest(). */
250 RTRCPTR pfnCPUMRCResumeGuest;
251 /** Resume Guest Execution in V86 mode. See CPUMGCResumeGuestV86(). */
252 RTRCPTR pfnCPUMRCResumeGuestV86;
253 /** Call Trampoline. See vmmGCCallTrampoline(). */
254 RTRCPTR pfnCallTrampolineRC;
255 /** Guest to host switcher entry point. */
256 RCPTRTYPE(PFNVMMSWITCHERRC) pfnRCToHost;
257 /** Host to guest switcher entry point. */
258 R0PTRTYPE(PFNVMMSWITCHERHC) pfnR0ToRawMode;
259 /** @} */
260
261 /** @name Logging
262 * @{
263 */
264 /** Size of the allocated logger instance (pRCLoggerRC/pRCLoggerR3). */
265 uint32_t cbRCLogger;
266 /** Pointer to the RC logger instance - RC Ptr.
267 * This is NULL if logging is disabled. */
268 RCPTRTYPE(PRTLOGGERRC) pRCLoggerRC;
269 /** Pointer to the GC logger instance - R3 Ptr.
270 * This is NULL if logging is disabled. */
271 R3PTRTYPE(PRTLOGGERRC) pRCLoggerR3;
272 /** Pointer to the GC release logger instance - R3 Ptr. */
273 R3PTRTYPE(PRTLOGGERRC) pRCRelLoggerR3;
274 /** Pointer to the GC release logger instance - RC Ptr. */
275 RCPTRTYPE(PRTLOGGERRC) pRCRelLoggerRC;
276 /** Size of the allocated release logger instance (pRCRelLoggerRC/pRCRelLoggerR3).
277 * This may differ from cbRCLogger. */
278 uint32_t cbRCRelLogger;
279 /** Whether log flushing has been disabled or not. */
280 bool fRCLoggerFlushingDisabled;
281 bool afAlignment1[5]; /**< Alignment padding. */
282 /** @} */
283
284 /** Whether the stack guard pages have been stationed or not. */
285 bool fStackGuardsStationed;
286 /** Whether we should use the periodic preemption timers. */
287 bool fUsePeriodicPreemptionTimers;
288
289 /** The EMT yield timer. */
290 PTMTIMERR3 pYieldTimer;
291 /** The period to the next timeout when suspended or stopped.
292 * This is 0 when running. */
293 uint32_t cYieldResumeMillies;
294 /** The EMT yield timer interval (milliseconds). */
295 uint32_t cYieldEveryMillies;
296 /** The timestamp of the previous yield. (nano) */
297 uint64_t u64LastYield;
298
299 /** @name EMT Rendezvous
300 * @{ */
301 /** Semaphore to wait on upon entering ordered execution. */
302 R3PTRTYPE(PRTSEMEVENT) pahEvtRendezvousEnterOrdered;
303 /** Semaphore to wait on upon entering for one-by-one execution. */
304 RTSEMEVENT hEvtRendezvousEnterOneByOne;
305 /** Semaphore to wait on upon entering for all-at-once execution. */
306 RTSEMEVENTMULTI hEvtMulRendezvousEnterAllAtOnce;
307 /** Semaphore to wait on when done. */
308 RTSEMEVENTMULTI hEvtMulRendezvousDone;
309 /** Semaphore the VMMR3EmtRendezvous caller waits on at the end. */
310 RTSEMEVENT hEvtRendezvousDoneCaller;
311 /** Semaphore to wait on upon recursing. */
312 RTSEMEVENTMULTI hEvtMulRendezvousRecursionPush;
313 /** Semaphore to wait on after done with recursion (caller restoring state). */
314 RTSEMEVENTMULTI hEvtMulRendezvousRecursionPop;
315 /** Semaphore the initiator waits on while the EMTs are getting into position
316 * on hEvtMulRendezvousRecursionPush. */
317 RTSEMEVENT hEvtRendezvousRecursionPushCaller;
318 /** Semaphore the initiator waits on while the EMTs sitting on
319 * hEvtMulRendezvousRecursionPop wakes up and leave. */
320 RTSEMEVENT hEvtRendezvousRecursionPopCaller;
321 /** Callback. */
322 R3PTRTYPE(PFNVMMEMTRENDEZVOUS) volatile pfnRendezvous;
323 /** The user argument for the callback. */
324 RTR3PTR volatile pvRendezvousUser;
325 /** Flags. */
326 volatile uint32_t fRendezvousFlags;
327 /** The number of EMTs that has entered. */
328 volatile uint32_t cRendezvousEmtsEntered;
329 /** The number of EMTs that has done their job. */
330 volatile uint32_t cRendezvousEmtsDone;
331 /** The number of EMTs that has returned. */
332 volatile uint32_t cRendezvousEmtsReturned;
333 /** The status code. */
334 volatile int32_t i32RendezvousStatus;
335 /** Spin lock. */
336 volatile uint32_t u32RendezvousLock;
337 /** The recursion depth. */
338 volatile uint32_t cRendezvousRecursions;
339 /** The number of EMTs that have entered the recursion routine. */
340 volatile uint32_t cRendezvousEmtsRecursingPush;
341 /** The number of EMTs that have leaft the recursion routine. */
342 volatile uint32_t cRendezvousEmtsRecursingPop;
343 /** Triggers rendezvous recursion in the other threads. */
344 volatile bool fRendezvousRecursion;
345
346 /** @} */
347
348 /** RTThreadPreemptIsPendingTrusty() result, set by vmmR0InitVM() for
349 * release logging purposes. */
350 bool fIsPreemptPendingApiTrusty : 1;
351 /** The RTThreadPreemptIsPossible() result, set by vmmR0InitVM() for
352 * release logging purposes. */
353 bool fIsPreemptPossible : 1;
354
355 bool afAlignment2[HC_ARCH_BITS == 32 ? 6 : 2]; /**< Alignment padding. */
356
357 /** Buffer for storing the standard assertion message for a ring-0 assertion.
358 * Used for saving the assertion message text for the release log and guru
359 * meditation dump. */
360 char szRing0AssertMsg1[512];
361 /** Buffer for storing the custom message for a ring-0 assertion. */
362 char szRing0AssertMsg2[256];
363
364 /** Number of VMMR0_DO_RUN_GC calls. */
365 STAMCOUNTER StatRunRC;
366
367 /** Statistics for each of the RC/R0 return codes.
368 * @{ */
369 STAMCOUNTER StatRZRetNormal;
370 STAMCOUNTER StatRZRetInterrupt;
371 STAMCOUNTER StatRZRetInterruptHyper;
372 STAMCOUNTER StatRZRetGuestTrap;
373 STAMCOUNTER StatRZRetRingSwitch;
374 STAMCOUNTER StatRZRetRingSwitchInt;
375 STAMCOUNTER StatRZRetStaleSelector;
376 STAMCOUNTER StatRZRetIRETTrap;
377 STAMCOUNTER StatRZRetEmulate;
378 STAMCOUNTER StatRZRetPatchEmulate;
379 STAMCOUNTER StatRZRetIORead;
380 STAMCOUNTER StatRZRetIOWrite;
381 STAMCOUNTER StatRZRetIOCommitWrite;
382 STAMCOUNTER StatRZRetMMIORead;
383 STAMCOUNTER StatRZRetMMIOWrite;
384 STAMCOUNTER StatRZRetMMIOCommitWrite;
385 STAMCOUNTER StatRZRetMMIOPatchRead;
386 STAMCOUNTER StatRZRetMMIOPatchWrite;
387 STAMCOUNTER StatRZRetMMIOReadWrite;
388 STAMCOUNTER StatRZRetMSRRead;
389 STAMCOUNTER StatRZRetMSRWrite;
390 STAMCOUNTER StatRZRetLDTFault;
391 STAMCOUNTER StatRZRetGDTFault;
392 STAMCOUNTER StatRZRetIDTFault;
393 STAMCOUNTER StatRZRetTSSFault;
394 STAMCOUNTER StatRZRetCSAMTask;
395 STAMCOUNTER StatRZRetSyncCR3;
396 STAMCOUNTER StatRZRetMisc;
397 STAMCOUNTER StatRZRetPatchInt3;
398 STAMCOUNTER StatRZRetPatchPF;
399 STAMCOUNTER StatRZRetPatchGP;
400 STAMCOUNTER StatRZRetPatchIretIRQ;
401 STAMCOUNTER StatRZRetRescheduleREM;
402 STAMCOUNTER StatRZRetToR3Total;
403 STAMCOUNTER StatRZRetToR3FF;
404 STAMCOUNTER StatRZRetToR3Unknown;
405 STAMCOUNTER StatRZRetToR3TMVirt;
406 STAMCOUNTER StatRZRetToR3HandyPages;
407 STAMCOUNTER StatRZRetToR3PDMQueues;
408 STAMCOUNTER StatRZRetToR3Rendezvous;
409 STAMCOUNTER StatRZRetToR3Timer;
410 STAMCOUNTER StatRZRetToR3DMA;
411 STAMCOUNTER StatRZRetToR3CritSect;
412 STAMCOUNTER StatRZRetToR3Iem;
413 STAMCOUNTER StatRZRetToR3Iom;
414 STAMCOUNTER StatRZRetTimerPending;
415 STAMCOUNTER StatRZRetInterruptPending;
416 STAMCOUNTER StatRZRetCallRing3;
417 STAMCOUNTER StatRZRetPATMDuplicateFn;
418 STAMCOUNTER StatRZRetPGMChangeMode;
419 STAMCOUNTER StatRZRetPendingRequest;
420 STAMCOUNTER StatRZRetPGMFlushPending;
421 STAMCOUNTER StatRZRetPatchTPR;
422 STAMCOUNTER StatRZCallPDMCritSectEnter;
423 STAMCOUNTER StatRZCallPDMLock;
424 STAMCOUNTER StatRZCallLogFlush;
425 STAMCOUNTER StatRZCallPGMPoolGrow;
426 STAMCOUNTER StatRZCallPGMMapChunk;
427 STAMCOUNTER StatRZCallPGMAllocHandy;
428 STAMCOUNTER StatRZCallRemReplay;
429 STAMCOUNTER StatRZCallVMSetError;
430 STAMCOUNTER StatRZCallVMSetRuntimeError;
431 STAMCOUNTER StatRZCallPGMLock;
432 /** @} */
433} VMM;
434/** Pointer to VMM. */
435typedef VMM *PVMM;
436
437
438/**
439 * VMMCPU Data (part of VMCPU)
440 */
441typedef struct VMMCPU
442{
443 /** Offset to the VMCPU structure.
444 * See VMM2VMCPU(). */
445 int32_t offVMCPU;
446
447 /** The last RC/R0 return code. */
448 int32_t iLastGZRc;
449
450 /** VMM stack, pointer to the top of the stack in R3.
451 * Stack is allocated from the hypervisor heap and is page aligned
452 * and always writable in RC. */
453 R3PTRTYPE(uint8_t *) pbEMTStackR3;
454 /** Pointer to the bottom of the stack - needed for doing relocations. */
455 RCPTRTYPE(uint8_t *) pbEMTStackRC;
456 /** Pointer to the bottom of the stack - needed for doing relocations. */
457 RCPTRTYPE(uint8_t *) pbEMTStackBottomRC;
458
459 /** Pointer to the R0 logger instance - R3 Ptr.
460 * This is NULL if logging is disabled. */
461 R3PTRTYPE(PVMMR0LOGGER) pR0LoggerR3;
462 /** Pointer to the R0 logger instance - R0 Ptr.
463 * This is NULL if logging is disabled. */
464 R0PTRTYPE(PVMMR0LOGGER) pR0LoggerR0;
465
466 /** Pointer to the R0 release logger instance - R3 Ptr.
467 * This is NULL if logging is disabled. */
468 R3PTRTYPE(PVMMR0LOGGER) pR0RelLoggerR3;
469 /** Pointer to the R0 release instance - R0 Ptr.
470 * This is NULL if logging is disabled. */
471 R0PTRTYPE(PVMMR0LOGGER) pR0RelLoggerR0;
472
473 /** Thread context switching hook (ring-0). */
474 RTTHREADCTXHOOK hCtxHook;
475
476 /** @name Rendezvous
477 * @{ */
478 /** Whether the EMT is executing a rendezvous right now. For detecting
479 * attempts at recursive rendezvous. */
480 bool volatile fInRendezvous;
481 bool afPadding[HC_ARCH_BITS == 32 ? 2 : 6+4];
482 /** @} */
483
484 /** Whether we can HLT in VMMR0 rather than having to return to EM.
485 * Updated by vmR3SetHaltMethodU(). */
486 bool fMayHaltInRing0;
487 /** The minimum delta for which we can HLT in ring-0 for.
488 * The deadlines we can calculate are from TM, so, if it's too close
489 * we should just return to ring-3 and run the timer wheel, no point
490 * in spinning in ring-0.
491 * Updated by vmR3SetHaltMethodU(). */
492 uint32_t cNsSpinBlockThreshold;
493 /** Number of ring-0 halts (used for depreciating following values). */
494 uint32_t cR0Halts;
495 /** Number of ring-0 halts succeeding (VINF_SUCCESS) recently. */
496 uint32_t cR0HaltsSucceeded;
497 /** Number of ring-0 halts failing (VINF_EM_HALT) recently. */
498 uint32_t cR0HaltsToRing3;
499 /** Padding */
500 uint32_t u32Padding0;
501
502 /** @name Raw-mode context tracing data.
503 * @{ */
504 SUPDRVTRACERUSRCTX TracerCtx;
505 /** @} */
506
507 /** Alignment padding, making sure u64CallRing3Arg is nicely aligned. */
508 uint32_t au32Padding1[3];
509
510 /** @name Call Ring-3
511 * Formerly known as host calls.
512 * @{ */
513 /** The disable counter. */
514 uint32_t cCallRing3Disabled;
515 /** The pending operation. */
516 VMMCALLRING3 enmCallRing3Operation;
517 /** The result of the last operation. */
518 int32_t rcCallRing3;
519 /** The argument to the operation. */
520 uint64_t u64CallRing3Arg;
521 /** The Ring-0 notification callback. */
522 R0PTRTYPE(PFNVMMR0CALLRING3NOTIFICATION) pfnCallRing3CallbackR0;
523 /** The Ring-0 notification callback user argument. */
524 R0PTRTYPE(void *) pvCallRing3CallbackUserR0;
525 /** The Ring-0 jmp buffer.
526 * @remarks The size of this type isn't stable in assembly, so don't put
527 * anything that needs to be accessed from assembly after it. */
528 VMMR0JMPBUF CallRing3JmpBufR0;
529 /** @} */
530
531 STAMPROFILE StatR0HaltBlock;
532 STAMPROFILE StatR0HaltBlockOnTime;
533 STAMPROFILE StatR0HaltBlockOverslept;
534 STAMPROFILE StatR0HaltBlockInsomnia;
535 STAMCOUNTER StatR0HaltExec;
536 STAMCOUNTER StatR0HaltExecFromBlock;
537 STAMCOUNTER StatR0HaltExecFromSpin;
538 STAMCOUNTER StatR0HaltToR3FromSpin;
539} VMMCPU;
540AssertCompileMemberAlignment(VMMCPU, TracerCtx, 8);
541/** Pointer to VMMCPU. */
542typedef VMMCPU *PVMMCPU;
543
544
545/**
546 * The VMMRCEntry() codes.
547 */
548typedef enum VMMRCOPERATION
549{
550 /** Do GC module init. */
551 VMMRC_DO_VMMRC_INIT = 1,
552
553 /** The first Trap testcase. */
554 VMMRC_DO_TESTCASE_TRAP_FIRST = 0x0dead000,
555 /** Trap 0 testcases, uArg selects the variation. */
556 VMMRC_DO_TESTCASE_TRAP_0 = VMMRC_DO_TESTCASE_TRAP_FIRST,
557 /** Trap 1 testcases, uArg selects the variation. */
558 VMMRC_DO_TESTCASE_TRAP_1,
559 /** Trap 2 testcases, uArg selects the variation. */
560 VMMRC_DO_TESTCASE_TRAP_2,
561 /** Trap 3 testcases, uArg selects the variation. */
562 VMMRC_DO_TESTCASE_TRAP_3,
563 /** Trap 4 testcases, uArg selects the variation. */
564 VMMRC_DO_TESTCASE_TRAP_4,
565 /** Trap 5 testcases, uArg selects the variation. */
566 VMMRC_DO_TESTCASE_TRAP_5,
567 /** Trap 6 testcases, uArg selects the variation. */
568 VMMRC_DO_TESTCASE_TRAP_6,
569 /** Trap 7 testcases, uArg selects the variation. */
570 VMMRC_DO_TESTCASE_TRAP_7,
571 /** Trap 8 testcases, uArg selects the variation. */
572 VMMRC_DO_TESTCASE_TRAP_8,
573 /** Trap 9 testcases, uArg selects the variation. */
574 VMMRC_DO_TESTCASE_TRAP_9,
575 /** Trap 0a testcases, uArg selects the variation. */
576 VMMRC_DO_TESTCASE_TRAP_0A,
577 /** Trap 0b testcases, uArg selects the variation. */
578 VMMRC_DO_TESTCASE_TRAP_0B,
579 /** Trap 0c testcases, uArg selects the variation. */
580 VMMRC_DO_TESTCASE_TRAP_0C,
581 /** Trap 0d testcases, uArg selects the variation. */
582 VMMRC_DO_TESTCASE_TRAP_0D,
583 /** Trap 0e testcases, uArg selects the variation. */
584 VMMRC_DO_TESTCASE_TRAP_0E,
585 /** The last trap testcase (exclusive). */
586 VMMRC_DO_TESTCASE_TRAP_LAST,
587 /** Testcase for checking interrupt forwarding. */
588 VMMRC_DO_TESTCASE_HYPER_INTERRUPT,
589 /** Switching testing and profiling stub. */
590 VMMRC_DO_TESTCASE_NOP,
591 /** Testcase for checking interrupt masking. */
592 VMMRC_DO_TESTCASE_INTERRUPT_MASKING,
593 /** Switching testing and profiling stub. */
594 VMMRC_DO_TESTCASE_HM_NOP,
595
596 /** The usual 32-bit hack. */
597 VMMRC_DO_32_BIT_HACK = 0x7fffffff
598} VMMRCOPERATION;
599
600
601
602/**
603 * MSR test result entry.
604 */
605typedef struct VMMTESTMSRENTRY
606{
607 /** The MSR number, including padding.
608 * Set to UINT64_MAX if invalid MSR. */
609 uint64_t uMsr;
610 /** The register value. */
611 uint64_t uValue;
612} VMMTESTMSRENTRY;
613/** Pointer to an MSR test result entry. */
614typedef VMMTESTMSRENTRY *PVMMTESTMSRENTRY;
615
616
617
618RT_C_DECLS_BEGIN
619
620int vmmInitFormatTypes(void);
621void vmmTermFormatTypes(void);
622uint32_t vmmGetBuildType(void);
623
624#ifdef IN_RING3
625int vmmR3SwitcherInit(PVM pVM);
626void vmmR3SwitcherRelocate(PVM pVM, RTGCINTPTR offDelta);
627#endif /* IN_RING3 */
628
629#ifdef IN_RING0
630/**
631 * World switcher assembly routine.
632 * It will call VMMRCEntry().
633 *
634 * @returns return code from VMMRCEntry().
635 * @param pVM The cross context VM structure.
636 * @param uArg See VMMRCEntry().
637 * @internal
638 */
639DECLASM(int) vmmR0WorldSwitch(PVM pVM, unsigned uArg);
640
641/**
642 * Callback function for vmmR0CallRing3SetJmp.
643 *
644 * @returns VBox status code.
645 * @param pVM The cross context VM structure.
646 */
647typedef DECLCALLBACK(int) FNVMMR0SETJMP(PVM pVM, PVMCPU pVCpu);
648/** Pointer to FNVMMR0SETJMP(). */
649typedef FNVMMR0SETJMP *PFNVMMR0SETJMP;
650
651/**
652 * The setjmp variant used for calling Ring-3.
653 *
654 * This differs from the normal setjmp in that it will resume VMMRZCallRing3 if we're
655 * in the middle of a ring-3 call. Another differences is the function pointer and
656 * argument. This has to do with resuming code and the stack frame of the caller.
657 *
658 * @returns VINF_SUCCESS on success or whatever is passed to vmmR0CallRing3LongJmp.
659 * @param pJmpBuf The jmp_buf to set.
660 * @param pfn The function to be called when not resuming.
661 * @param pVM The cross context VM structure.
662 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
663 */
664DECLASM(int) vmmR0CallRing3SetJmp(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMP pfn, PVM pVM, PVMCPU pVCpu);
665
666
667/**
668 * Callback function for vmmR0CallRing3SetJmp2.
669 *
670 * @returns VBox status code.
671 * @param pvUser The user argument.
672 */
673typedef DECLCALLBACK(int) FNVMMR0SETJMP2(PGVM pGVM, VMCPUID idCpu);
674/** Pointer to FNVMMR0SETJMP2(). */
675typedef FNVMMR0SETJMP2 *PFNVMMR0SETJMP2;
676
677/**
678 * Same as vmmR0CallRing3SetJmp except for the function signature.
679 *
680 * @returns VINF_SUCCESS on success or whatever is passed to vmmR0CallRing3LongJmp.
681 * @param pJmpBuf The jmp_buf to set.
682 * @param pfn The function to be called when not resuming.
683 * @param pGVM The ring-0 VM structure.
684 * @param idCpu The ID of the calling EMT.
685 */
686DECLASM(int) vmmR0CallRing3SetJmp2(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMP2 pfn, PGVM pGVM, VMCPUID idCpu);
687
688
689/**
690 * Callback function for vmmR0CallRing3SetJmpEx.
691 *
692 * @returns VBox status code.
693 * @param pvUser The user argument.
694 */
695typedef DECLCALLBACK(int) FNVMMR0SETJMPEX(void *pvUser);
696/** Pointer to FNVMMR0SETJMPEX(). */
697typedef FNVMMR0SETJMPEX *PFNVMMR0SETJMPEX;
698
699/**
700 * Same as vmmR0CallRing3SetJmp except for the function signature.
701 *
702 * @returns VINF_SUCCESS on success or whatever is passed to vmmR0CallRing3LongJmp.
703 * @param pJmpBuf The jmp_buf to set.
704 * @param pfn The function to be called when not resuming.
705 * @param pvUser The argument of that function.
706 */
707DECLASM(int) vmmR0CallRing3SetJmpEx(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMPEX pfn, void *pvUser);
708
709
710/**
711 * Worker for VMMRZCallRing3.
712 * This will save the stack and registers.
713 *
714 * @returns rc.
715 * @param pJmpBuf Pointer to the jump buffer.
716 * @param rc The return code.
717 */
718DECLASM(int) vmmR0CallRing3LongJmp(PVMMR0JMPBUF pJmpBuf, int rc);
719
720/**
721 * Internal R0 logger worker: Logger wrapper.
722 */
723VMMR0DECL(void) vmmR0LoggerWrapper(const char *pszFormat, ...);
724
725/**
726 * Internal R0 logger worker: Flush logger.
727 *
728 * @param pLogger The logger instance to flush.
729 * @remark This function must be exported!
730 */
731VMMR0DECL(void) vmmR0LoggerFlush(PRTLOGGER pLogger);
732
733/**
734 * Internal R0 logger worker: Custom prefix.
735 *
736 * @returns Number of chars written.
737 *
738 * @param pLogger The logger instance.
739 * @param pchBuf The output buffer.
740 * @param cchBuf The size of the buffer.
741 * @param pvUser User argument (ignored).
742 */
743VMMR0DECL(size_t) vmmR0LoggerPrefix(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser);
744
745# ifdef VBOX_WITH_TRIPLE_FAULT_HACK
746int vmmR0TripleFaultHackInit(void);
747void vmmR0TripleFaultHackTerm(void);
748# endif
749
750#endif /* IN_RING0 */
751#ifdef IN_RC
752
753/**
754 * Internal GC logger worker: Logger wrapper.
755 */
756VMMRCDECL(void) vmmGCLoggerWrapper(const char *pszFormat, ...);
757
758/**
759 * Internal GC release logger worker: Logger wrapper.
760 */
761VMMRCDECL(void) vmmGCRelLoggerWrapper(const char *pszFormat, ...);
762
763/**
764 * Internal GC logger worker: Flush logger.
765 *
766 * @returns VINF_SUCCESS.
767 * @param pLogger The logger instance to flush.
768 * @remark This function must be exported!
769 */
770VMMRCDECL(int) vmmGCLoggerFlush(PRTLOGGERRC pLogger);
771
772/** @name Trap testcases and related labels.
773 * @{ */
774DECLASM(void) vmmGCEnableWP(void);
775DECLASM(void) vmmGCDisableWP(void);
776DECLASM(int) vmmGCTestTrap3(void);
777DECLASM(int) vmmGCTestTrap8(void);
778DECLASM(int) vmmGCTestTrap0d(void);
779DECLASM(int) vmmGCTestTrap0e(void);
780DECLASM(int) vmmGCTestTrap0e_FaultEIP(void); /**< a label */
781DECLASM(int) vmmGCTestTrap0e_ResumeEIP(void); /**< a label */
782/** @} */
783
784#endif /* IN_RC */
785
786RT_C_DECLS_END
787
788/** @} */
789
790#endif /* !VMM_INCLUDED_SRC_include_VMMInternal_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