VirtualBox

source: vbox/trunk/include/VBox/vm.h@ 6981

Last change on this file since 6981 was 6834, checked in by vboxsync, 17 years ago

Added VM_ASSERT_STATE[_RETURN].

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.4 KB
Line 
1/** @file
2 * VM - The Virtual Machine, data.
3 */
4
5/*
6 * Copyright (C) 2006-2007 innotek GmbH
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_vm_h
27#define ___VBox_vm_h
28
29#include <VBox/cdefs.h>
30#include <VBox/types.h>
31#include <VBox/cpum.h>
32#include <VBox/stam.h>
33#include <VBox/vmapi.h>
34#include <VBox/sup.h>
35
36
37/** @defgroup grp_vm The Virtual Machine
38 * @{
39 */
40
41/** The name of the Guest Context VMM Core module. */
42#define VMMGC_MAIN_MODULE_NAME "VMMGC.gc"
43/** The name of the Ring 0 Context VMM Core module. */
44#define VMMR0_MAIN_MODULE_NAME "VMMR0.r0"
45
46/** VM Forced Action Flags.
47 *
48 * Use the VM_FF_SET() and VM_FF_CLEAR() macros to change the force
49 * action mask of a VM.
50 *
51 * @{
52 */
53/** This action forces the VM to service check and pending interrups on the APIC. */
54#define VM_FF_INTERRUPT_APIC RT_BIT_32(0)
55/** This action forces the VM to service check and pending interrups on the PIC. */
56#define VM_FF_INTERRUPT_PIC RT_BIT_32(1)
57/** This action forces the VM to schedule and run pending timer (TM). */
58#define VM_FF_TIMER RT_BIT_32(2)
59/** PDM Queues are pending. */
60#define VM_FF_PDM_QUEUES RT_BIT_32(3)
61/** PDM DMA transfers are pending. */
62#define VM_FF_PDM_DMA RT_BIT_32(4)
63/** PDM critical section unlocking is pending, process promptly upon return to R3. */
64#define VM_FF_PDM_CRITSECT RT_BIT_32(5)
65
66/** This action forces the VM to call DBGF so DBGF can service debugger
67 * requests in the emulation thread.
68 * This action flag stays asserted till DBGF clears it.*/
69#define VM_FF_DBGF RT_BIT_32(8)
70/** This action forces the VM to service pending requests from other
71 * thread or requests which must be executed in another context. */
72#define VM_FF_REQUEST RT_BIT_32(9)
73/** Terminate the VM immediately. */
74#define VM_FF_TERMINATE RT_BIT_32(10)
75/** Reset the VM. (postponed) */
76#define VM_FF_RESET RT_BIT_32(11)
77
78/** This action forces the VM to resync the page tables before going
79 * back to execute guest code. (GLOBAL FLUSH) */
80#define VM_FF_PGM_SYNC_CR3 RT_BIT_32(16)
81/** Same as VM_FF_PGM_SYNC_CR3 except that global pages can be skipped.
82 * (NON-GLOBAL FLUSH) */
83#define VM_FF_PGM_SYNC_CR3_NON_GLOBAL RT_BIT_32(17)
84/** PGM needs to allocate handy pages. */
85#define VM_FF_PGM_NEED_HANDY_PAGES RT_BIT_32(18)
86/** Check the interupt and trap gates */
87#define VM_FF_TRPM_SYNC_IDT RT_BIT_32(19)
88/** Check Guest's TSS ring 0 stack */
89#define VM_FF_SELM_SYNC_TSS RT_BIT_32(20)
90/** Check Guest's GDT table */
91#define VM_FF_SELM_SYNC_GDT RT_BIT_32(21)
92/** Check Guest's LDT table */
93#define VM_FF_SELM_SYNC_LDT RT_BIT_32(22)
94/** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */
95#define VM_FF_INHIBIT_INTERRUPTS RT_BIT_32(23)
96
97/** CSAM needs to scan the page that's being executed */
98#define VM_FF_CSAM_SCAN_PAGE RT_BIT_32(24)
99/** CSAM needs to do some homework. */
100#define VM_FF_CSAM_PENDING_ACTION RT_BIT_32(25)
101
102/** Force return to Ring-3. */
103#define VM_FF_TO_R3 RT_BIT_32(28)
104
105/** Suspend the VM - debug only. */
106#define VM_FF_DEBUG_SUSPEND RT_BIT_32(31)
107
108/** Externally forced actions. Used to quit the idle/wait loop. */
109#define VM_FF_EXTERNAL_SUSPENDED_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_REQUEST)
110/** Externally forced actions. Used to quit the idle/wait loop. */
111#define VM_FF_EXTERNAL_HALTED_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA)
112/** High priority pre-execution actions. */
113#define VM_FF_HIGH_PRIORITY_PRE_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_DEBUG_SUSPEND \
114 | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_PGM_NEED_HANDY_PAGES)
115/** High priority pre raw-mode execution mask. */
116#define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK (VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_PGM_NEED_HANDY_PAGES \
117 | VM_FF_INHIBIT_INTERRUPTS)
118/** High priority post-execution actions. */
119#define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PDM_CRITSECT | VM_FF_CSAM_PENDING_ACTION)
120/** Normal priority post-execution actions. */
121#define VM_FF_NORMAL_PRIORITY_POST_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE)
122/** Normal priority actions. */
123#define VM_FF_NORMAL_PRIORITY_MASK (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA)
124/** Flags to check before resuming guest execution. */
125#define VM_FF_RESUME_GUEST_MASK (VM_FF_TO_R3)
126/** All the forced flags. */
127#define VM_FF_ALL_MASK (~0U)
128/** All the forced flags. */
129#define VM_FF_ALL_BUT_RAW_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_CSAM_PENDING_ACTION | VM_FF_PDM_CRITSECT))
130
131/** @} */
132
133/** @def VM_FF_SET
134 * Sets a force action flag.
135 *
136 * @param pVM VM Handle.
137 * @param fFlag The flag to set.
138 */
139#if 1
140# define VM_FF_SET(pVM, fFlag) ASMAtomicOrU32(&(pVM)->fForcedActions, (fFlag))
141#else
142# define VM_FF_SET(pVM, fFlag) \
143 do { ASMAtomicOrU32(&(pVM)->fForcedActions, (fFlag)); \
144 RTLogPrintf("VM_FF_SET : %08x %s - %s(%d) %s\n", (pVM)->fForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
145 } while (0)
146#endif
147
148/** @def VM_FF_CLEAR
149 * Clears a force action flag.
150 *
151 * @param pVM VM Handle.
152 * @param fFlag The flag to clear.
153 */
154#if 1
155# define VM_FF_CLEAR(pVM, fFlag) ASMAtomicAndU32(&(pVM)->fForcedActions, ~(fFlag))
156#else
157# define VM_FF_CLEAR(pVM, fFlag) \
158 do { ASMAtomicAndU32(&(pVM)->fForcedActions, ~(fFlag)); \
159 RTLogPrintf("VM_FF_CLEAR: %08x %s - %s(%d) %s\n", (pVM)->fForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
160 } while (0)
161#endif
162
163/** @def VM_FF_ISSET
164 * Checks if a force action flag is set.
165 *
166 * @param pVM VM Handle.
167 * @param fFlag The flag to check.
168 */
169#define VM_FF_ISSET(pVM, fFlag) (((pVM)->fForcedActions & (fFlag)) == (fFlag))
170
171/** @def VM_FF_ISPENDING
172 * Checks if one or more force action in the specified set is pending.
173 *
174 * @param pVM VM Handle.
175 * @param fFlags The flags to check for.
176 */
177#define VM_FF_ISPENDING(pVM, fFlags) ((pVM)->fForcedActions & (fFlags))
178
179
180/** @def VM_IS_EMT
181 * Checks if the current thread is the emulation thread (EMT).
182 *
183 * @remark The ring-0 variation will need attention if we expand the ring-0
184 * code to let threads other than EMT mess around with the VM.
185 */
186#ifdef IN_GC
187# define VM_IS_EMT(pVM) true
188#elif defined(IN_RING0)
189# define VM_IS_EMT(pVM) true
190#else
191# define VM_IS_EMT(pVM) ((pVM)->NativeThreadEMT == RTThreadNativeSelf())
192#endif
193
194/** @def VM_ASSERT_EMT
195 * Asserts that the current thread IS the emulation thread (EMT).
196 */
197#ifdef IN_GC
198# define VM_ASSERT_EMT(pVM) Assert(VM_IS_EMT(pVM))
199#elif defined(IN_RING0)
200# define VM_ASSERT_EMT(pVM) Assert(VM_IS_EMT(pVM))
201#else
202# define VM_ASSERT_EMT(pVM) \
203 AssertMsg(VM_IS_EMT(pVM), \
204 ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd\n", RTThreadNativeSelf(), pVM->NativeThreadEMT))
205#endif
206
207/** @def VM_ASSERT_EMT_RETURN
208 * Asserts that the current thread IS the emulation thread (EMT) and returns if it isn't.
209 */
210#ifdef IN_GC
211# define VM_ASSERT_EMT_RETURN(pVM, rc) AssertReturn(VM_IS_EMT(pVM), (rc))
212#elif defined(IN_RING0)
213# define VM_ASSERT_EMT_RETURN(pVM, rc) AssertReturn(VM_IS_EMT(pVM), (rc))
214#else
215# define VM_ASSERT_EMT_RETURN(pVM, rc) \
216 AssertMsgReturn(VM_IS_EMT(pVM), \
217 ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd\n", RTThreadNativeSelf(), pVM->NativeThreadEMT), \
218 (rc))
219#endif
220
221/**
222 * Asserts that the current thread is NOT the emulation thread.
223 */
224#define VM_ASSERT_OTHER_THREAD(pVM) \
225 AssertMsg(!VM_IS_EMT(pVM), ("Not other thread!!\n"))
226
227
228/** @def VM_ASSERT_STATE_RETURN
229 * Asserts a certain VM state.
230 */
231#define VM_ASSERT_STATE(pVM, _enmState) \
232 AssertMsg((pVM)->enmVMState == (_enmState), \
233 ("state %s, expected %s\n", VMGetStateName(pVM->enmVMState), VMGetStateName(_enmState)))
234
235/** @def VM_ASSERT_STATE_RETURN
236 * Asserts a certain VM state and returns if it doesn't match.
237 */
238#define VM_ASSERT_STATE_RETURN(pVM, _enmState, rc) \
239 AssertMsgReturn((pVM)->enmVMState == (_enmState), \
240 ("state %s, expected %s\n", VMGetStateName(pVM->enmVMState), VMGetStateName(_enmState)), \
241 (rc))
242
243
244
245
246/** This is the VM structure.
247 *
248 * It contains (nearly?) all the VM data which have to be available in all
249 * contexts. Even if it contains all the data the idea is to use APIs not
250 * to modify all the members all around the place. Therefore we make use of
251 * unions to hide everything which isn't local to the current source module.
252 * This means we'll have to pay a little bit of attention when adding new
253 * members to structures in the unions and make sure to keep the padding sizes
254 * up to date.
255 *
256 * Run tstVMStructSize after update!
257 */
258typedef struct VM
259{
260 /** The state of the VM.
261 * This field is read only to everyone except the VM and EM. */
262 VMSTATE enmVMState;
263 /** Forced action flags.
264 * See the VM_FF_* \#defines. Updated atomically.
265 */
266 volatile uint32_t fForcedActions;
267 /** Pointer to the array of page descriptors for the VM structure allocation. */
268 R3PTRTYPE(PSUPPAGE) paVMPagesR3;
269 /** Session handle. For use when calling SUPR0 APIs. */
270 PSUPDRVSESSION pSession;
271 /** Pointer to the ring-3 VM structure. */
272 PUVM pUVM;
273 /** Ring-3 Host Context VM Pointer. */
274 R3PTRTYPE(struct VM *) pVMR3;
275 /** Ring-0 Host Context VM Pointer. */
276 R0PTRTYPE(struct VM *) pVMR0;
277 /** Guest Context VM Pointer. */
278 GCPTRTYPE(struct VM *) pVMGC;
279
280 /** The GVM VM handle. Only the GVM should modify this field. */
281 uint32_t hSelf;
282 /** Reserved / padding. */
283 uint32_t u32Reserved;
284
285 /** @name Public VMM Switcher APIs
286 * @{ */
287 /**
288 * Assembly switch entry point for returning to host context.
289 * This function will clean up the stack frame.
290 *
291 * @param eax The return code, register.
292 * @param Ctx The guest core context.
293 * @remark Assume interrupts disabled.
294 */
295 RTGCPTR pfnVMMGCGuestToHostAsmGuestCtx/*(int32_t eax, CPUMCTXCORE Ctx)*/;
296
297 /**
298 * Assembly switch entry point for returning to host context.
299 *
300 * This is an alternative entry point which we'll be using when the we have the
301 * hypervisor context and need to save that before going to the host.
302 *
303 * This is typically useful when abandoning the hypervisor because of a trap
304 * and want the trap state to be saved.
305 *
306 * @param eax The return code, register.
307 * @param ecx Pointer to the hypervisor core context, register.
308 * @remark Assume interrupts disabled.
309 */
310 RTGCPTR pfnVMMGCGuestToHostAsmHyperCtx/*(int32_t eax, PCPUMCTXCORE ecx)*/;
311
312 /**
313 * Assembly switch entry point for returning to host context.
314 *
315 * This is an alternative to the two *Ctx APIs and implies that the context has already
316 * been saved, or that it's just a brief return to HC and that the caller intends to resume
317 * whatever it is doing upon 'return' from this call.
318 *
319 * @param eax The return code, register.
320 * @remark Assume interrupts disabled.
321 */
322 RTGCPTR pfnVMMGCGuestToHostAsm/*(int32_t eax)*/;
323 /** @} */
324
325
326 /** @name Various VM data owned by VM.
327 * @{ */
328 /** The thread handle of the emulation thread.
329 * Use the VM_IS_EMT() macro to check if executing in EMT. */
330 RTTHREAD ThreadEMT;
331 /** The native handle of ThreadEMT. Getting the native handle
332 * is generally faster than getting the IPRT one (except on OS/2 :-). */
333 RTNATIVETHREAD NativeThreadEMT;
334 /** @} */
335
336
337 /** @name Various items that are frequently accessed.
338 * @{ */
339 /** Raw ring-3 indicator. */
340 bool fRawR3Enabled;
341 /** Raw ring-0 indicator. */
342 bool fRawR0Enabled;
343 /** PATM enabled flag.
344 * This is placed here for performance reasons. */
345 bool fPATMEnabled;
346 /** CSAM enabled flag.
347 * This is placed here for performance reasons. */
348 bool fCSAMEnabled;
349
350 /** Hardware VM support is available and enabled.
351 * This is placed here for performance reasons. */
352 bool fHWACCMEnabled;
353 /** @} */
354
355
356 /* padding to make gnuc put the StatQemuToGC where msc does. */
357#if HC_ARCH_BITS == 32
358 uint32_t padding0;
359#endif
360
361 /** Profiling the total time from Qemu to GC. */
362 STAMPROFILEADV StatTotalQemuToGC;
363 /** Profiling the total time from GC to Qemu. */
364 STAMPROFILEADV StatTotalGCToQemu;
365 /** Profiling the total time spent in GC. */
366 STAMPROFILEADV StatTotalInGC;
367 /** Profiling the total time spent not in Qemu. */
368 STAMPROFILEADV StatTotalInQemu;
369 /** Profiling the VMMSwitcher code for going to GC. */
370 STAMPROFILEADV StatSwitcherToGC;
371 /** Profiling the VMMSwitcher code for going to HC. */
372 STAMPROFILEADV StatSwitcherToHC;
373 STAMPROFILEADV StatSwitcherSaveRegs;
374 STAMPROFILEADV StatSwitcherSysEnter;
375 STAMPROFILEADV StatSwitcherDebug;
376 STAMPROFILEADV StatSwitcherCR0;
377 STAMPROFILEADV StatSwitcherCR4;
378 STAMPROFILEADV StatSwitcherJmpCR3;
379 STAMPROFILEADV StatSwitcherRstrRegs;
380 STAMPROFILEADV StatSwitcherLgdt;
381 STAMPROFILEADV StatSwitcherLidt;
382 STAMPROFILEADV StatSwitcherLldt;
383 STAMPROFILEADV StatSwitcherTSS;
384
385 /* padding - the unions must be aligned on 32 bytes boundraries. */
386 uint32_t padding[HC_ARCH_BITS == 32 ? 4 : 6];
387
388 /** CPUM part. */
389 union
390 {
391#ifdef ___CPUMInternal_h
392 struct CPUM s;
393#endif
394#ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
395 char padding[3648]; /* multiple of 32 */
396#else
397 char padding[HC_ARCH_BITS == 32 ? 3488 : 3616]; /* multiple of 32 */
398#endif
399 } cpum;
400
401 /** VMM part. */
402 union
403 {
404#ifdef ___VMMInternal_h
405 struct VMM s;
406#endif
407 char padding[1024]; /* multiple of 32 */
408 } vmm;
409
410 /** PGM part. */
411 union
412 {
413#ifdef ___PGMInternal_h
414 struct PGM s;
415#endif
416 char padding[50*1024]; /* multiple of 32 */
417 } pgm;
418
419 /** HWACCM part. */
420 union
421 {
422#ifdef ___HWACCMInternal_h
423 struct HWACCM s;
424#endif
425 char padding[1024]; /* multiple of 32 */
426 } hwaccm;
427
428 /** TRPM part. */
429 union
430 {
431#ifdef ___TRPMInternal_h
432 struct TRPM s;
433#endif
434 char padding[5344]; /* multiple of 32 */
435 } trpm;
436
437 /** SELM part. */
438 union
439 {
440#ifdef ___SELMInternal_h
441 struct SELM s;
442#endif
443 char padding[544]; /* multiple of 32 */
444 } selm;
445
446 /** MM part. */
447 union
448 {
449#ifdef ___MMInternal_h
450 struct MM s;
451#endif
452 char padding[128]; /* multiple of 32 */
453 } mm;
454
455 /** CFGM part. */
456 union
457 {
458#ifdef ___CFGMInternal_h
459 struct CFGM s;
460#endif
461 char padding[32]; /* multiple of 32 */
462 } cfgm;
463
464 /** PDM part. */
465 union
466 {
467#ifdef ___PDMInternal_h
468 struct PDM s;
469#endif
470 char padding[1024]; /* multiple of 32 */
471 } pdm;
472
473 /** IOM part. */
474 union
475 {
476#ifdef ___IOMInternal_h
477 struct IOM s;
478#endif
479 char padding[4544]; /* multiple of 32 */
480 } iom;
481
482 /** PATM part. */
483 union
484 {
485#ifdef ___PATMInternal_h
486 struct PATM s;
487#endif
488 char padding[768]; /* multiple of 32 */
489 } patm;
490
491 /** CSAM part. */
492 union
493 {
494#ifdef ___CSAMInternal_h
495 struct CSAM s;
496#endif
497 char padding[3328]; /* multiple of 32 */
498 } csam;
499
500 /** EM part. */
501 union
502 {
503#ifdef ___EMInternal_h
504 struct EM s;
505#endif
506 char padding[1344]; /* multiple of 32 */
507 } em;
508
509 /** TM part. */
510 union
511 {
512#ifdef ___TMInternal_h
513 struct TM s;
514#endif
515 char padding[1312]; /* multiple of 32 */
516 } tm;
517
518 /** DBGF part. */
519 union
520 {
521#ifdef ___DBGFInternal_h
522 struct DBGF s;
523#endif
524 char padding[HC_ARCH_BITS == 32 ? 1888 : 1920]; /* multiple of 32 */
525 } dbgf;
526
527 /** SSM part. */
528 union
529 {
530#ifdef ___SSMInternal_h
531 struct SSM s;
532#endif
533 char padding[32]; /* multiple of 32 */
534 } ssm;
535
536 /** VM part. */
537 union
538 {
539#ifdef ___VMInternal_h
540 struct VMINT s;
541#endif
542 char padding[768]; /* multiple of 32 */
543 } vm;
544
545 /** REM part. */
546 union
547 {
548#ifdef ___REMInternal_h
549 struct REM s;
550#endif
551 char padding[HC_ARCH_BITS == 32 ? 0x6b00 : 0xbf00]; /* multiple of 32 */
552 } rem;
553} VM;
554
555/** Pointer to a VM. */
556#ifndef ___VBox_types_h
557typedef struct VM *PVM;
558#endif
559
560
561#ifdef IN_GC
562__BEGIN_DECLS
563
564/** The VM structure.
565 * This is imported from the VMMGCBuiltin module, i.e. it's a one
566 * of those magic globals which we should avoid using.
567 */
568extern DECLIMPORT(VM) g_VM;
569
570__END_DECLS
571#endif
572
573/** @} */
574
575#endif
576
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