VirtualBox

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

Last change on this file since 9153 was 9148, checked in by vboxsync, 17 years ago

More 64 bits guest preps

  • 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 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___VBox_vm_h
31#define ___VBox_vm_h
32
33#include <VBox/cdefs.h>
34#include <VBox/types.h>
35#include <VBox/cpum.h>
36#include <VBox/stam.h>
37#include <VBox/vmapi.h>
38#include <VBox/sup.h>
39
40
41/** @defgroup grp_vm The Virtual Machine
42 * @{
43 */
44
45/** The name of the Guest Context VMM Core module. */
46#define VMMGC_MAIN_MODULE_NAME "VMMGC.gc"
47/** The name of the Ring 0 Context VMM Core module. */
48#define VMMR0_MAIN_MODULE_NAME "VMMR0.r0"
49
50/** VM Forced Action Flags.
51 *
52 * Use the VM_FF_SET() and VM_FF_CLEAR() macros to change the force
53 * action mask of a VM.
54 *
55 * @{
56 */
57/** This action forces the VM to service check and pending interrups on the APIC. */
58#define VM_FF_INTERRUPT_APIC RT_BIT_32(0)
59/** This action forces the VM to service check and pending interrups on the PIC. */
60#define VM_FF_INTERRUPT_PIC RT_BIT_32(1)
61/** This action forces the VM to schedule and run pending timer (TM). */
62#define VM_FF_TIMER RT_BIT_32(2)
63/** PDM Queues are pending. */
64#define VM_FF_PDM_QUEUES RT_BIT_32(3)
65/** PDM DMA transfers are pending. */
66#define VM_FF_PDM_DMA RT_BIT_32(4)
67/** PDM critical section unlocking is pending, process promptly upon return to R3. */
68#define VM_FF_PDM_CRITSECT RT_BIT_32(5)
69
70/** This action forces the VM to call DBGF so DBGF can service debugger
71 * requests in the emulation thread.
72 * This action flag stays asserted till DBGF clears it.*/
73#define VM_FF_DBGF RT_BIT_32(8)
74/** This action forces the VM to service pending requests from other
75 * thread or requests which must be executed in another context. */
76#define VM_FF_REQUEST RT_BIT_32(9)
77/** Terminate the VM immediately. */
78#define VM_FF_TERMINATE RT_BIT_32(10)
79/** Reset the VM. (postponed) */
80#define VM_FF_RESET RT_BIT_32(11)
81
82/** This action forces the VM to resync the page tables before going
83 * back to execute guest code. (GLOBAL FLUSH) */
84#define VM_FF_PGM_SYNC_CR3 RT_BIT_32(16)
85/** Same as VM_FF_PGM_SYNC_CR3 except that global pages can be skipped.
86 * (NON-GLOBAL FLUSH) */
87#define VM_FF_PGM_SYNC_CR3_NON_GLOBAL RT_BIT_32(17)
88/** PGM needs to allocate handy pages. */
89#define VM_FF_PGM_NEED_HANDY_PAGES RT_BIT_32(18)
90/** Check the interupt and trap gates */
91#define VM_FF_TRPM_SYNC_IDT RT_BIT_32(19)
92/** Check Guest's TSS ring 0 stack */
93#define VM_FF_SELM_SYNC_TSS RT_BIT_32(20)
94/** Check Guest's GDT table */
95#define VM_FF_SELM_SYNC_GDT RT_BIT_32(21)
96/** Check Guest's LDT table */
97#define VM_FF_SELM_SYNC_LDT RT_BIT_32(22)
98/** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */
99#define VM_FF_INHIBIT_INTERRUPTS RT_BIT_32(23)
100
101/** CSAM needs to scan the page that's being executed */
102#define VM_FF_CSAM_SCAN_PAGE RT_BIT_32(24)
103/** CSAM needs to do some homework. */
104#define VM_FF_CSAM_PENDING_ACTION RT_BIT_32(25)
105
106/** Force return to Ring-3. */
107#define VM_FF_TO_R3 RT_BIT_32(28)
108
109/** Suspend the VM - debug only. */
110#define VM_FF_DEBUG_SUSPEND RT_BIT_32(31)
111
112/** Externally forced actions. Used to quit the idle/wait loop. */
113#define VM_FF_EXTERNAL_SUSPENDED_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_REQUEST)
114/** Externally forced actions. Used to quit the idle/wait loop. */
115#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)
116/** High priority pre-execution actions. */
117#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 \
118 | 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)
119/** High priority pre raw-mode execution mask. */
120#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 \
121 | VM_FF_INHIBIT_INTERRUPTS)
122/** High priority post-execution actions. */
123#define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PDM_CRITSECT | VM_FF_CSAM_PENDING_ACTION)
124/** Normal priority post-execution actions. */
125#define VM_FF_NORMAL_PRIORITY_POST_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE)
126/** Normal priority actions. */
127#define VM_FF_NORMAL_PRIORITY_MASK (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA)
128/** Flags to check before resuming guest execution. */
129#define VM_FF_RESUME_GUEST_MASK (VM_FF_TO_R3)
130/** All the forced flags. */
131#define VM_FF_ALL_MASK (~0U)
132/** All the forced flags. */
133#define VM_FF_ALL_BUT_RAW_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_CSAM_PENDING_ACTION | VM_FF_PDM_CRITSECT))
134
135/** @} */
136
137/** @def VM_FF_SET
138 * Sets a force action flag.
139 *
140 * @param pVM VM Handle.
141 * @param fFlag The flag to set.
142 */
143#if 1
144# define VM_FF_SET(pVM, fFlag) ASMAtomicOrU32(&(pVM)->fForcedActions, (fFlag))
145#else
146# define VM_FF_SET(pVM, fFlag) \
147 do { ASMAtomicOrU32(&(pVM)->fForcedActions, (fFlag)); \
148 RTLogPrintf("VM_FF_SET : %08x %s - %s(%d) %s\n", (pVM)->fForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
149 } while (0)
150#endif
151
152/** @def VM_FF_CLEAR
153 * Clears a force action flag.
154 *
155 * @param pVM VM Handle.
156 * @param fFlag The flag to clear.
157 */
158#if 1
159# define VM_FF_CLEAR(pVM, fFlag) ASMAtomicAndU32(&(pVM)->fForcedActions, ~(fFlag))
160#else
161# define VM_FF_CLEAR(pVM, fFlag) \
162 do { ASMAtomicAndU32(&(pVM)->fForcedActions, ~(fFlag)); \
163 RTLogPrintf("VM_FF_CLEAR: %08x %s - %s(%d) %s\n", (pVM)->fForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
164 } while (0)
165#endif
166
167/** @def VM_FF_ISSET
168 * Checks if a force action flag is set.
169 *
170 * @param pVM VM Handle.
171 * @param fFlag The flag to check.
172 */
173#define VM_FF_ISSET(pVM, fFlag) (((pVM)->fForcedActions & (fFlag)) == (fFlag))
174
175/** @def VM_FF_ISPENDING
176 * Checks if one or more force action in the specified set is pending.
177 *
178 * @param pVM VM Handle.
179 * @param fFlags The flags to check for.
180 */
181#define VM_FF_ISPENDING(pVM, fFlags) ((pVM)->fForcedActions & (fFlags))
182
183
184/** @def VM_IS_EMT
185 * Checks if the current thread is the emulation thread (EMT).
186 *
187 * @remark The ring-0 variation will need attention if we expand the ring-0
188 * code to let threads other than EMT mess around with the VM.
189 */
190#ifdef IN_GC
191# define VM_IS_EMT(pVM) true
192#elif defined(IN_RING0)
193# define VM_IS_EMT(pVM) true
194#else
195# define VM_IS_EMT(pVM) ((pVM)->NativeThreadEMT == RTThreadNativeSelf())
196#endif
197
198/** @def VM_ASSERT_EMT
199 * Asserts that the current thread IS the emulation thread (EMT).
200 */
201#ifdef IN_GC
202# define VM_ASSERT_EMT(pVM) Assert(VM_IS_EMT(pVM))
203#elif defined(IN_RING0)
204# define VM_ASSERT_EMT(pVM) Assert(VM_IS_EMT(pVM))
205#else
206# define VM_ASSERT_EMT(pVM) \
207 AssertMsg(VM_IS_EMT(pVM), \
208 ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd\n", RTThreadNativeSelf(), pVM->NativeThreadEMT))
209#endif
210
211/** @def VM_ASSERT_EMT_RETURN
212 * Asserts that the current thread IS the emulation thread (EMT) and returns if it isn't.
213 */
214#ifdef IN_GC
215# define VM_ASSERT_EMT_RETURN(pVM, rc) AssertReturn(VM_IS_EMT(pVM), (rc))
216#elif defined(IN_RING0)
217# define VM_ASSERT_EMT_RETURN(pVM, rc) AssertReturn(VM_IS_EMT(pVM), (rc))
218#else
219# define VM_ASSERT_EMT_RETURN(pVM, rc) \
220 AssertMsgReturn(VM_IS_EMT(pVM), \
221 ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd\n", RTThreadNativeSelf(), pVM->NativeThreadEMT), \
222 (rc))
223#endif
224
225/**
226 * Asserts that the current thread is NOT the emulation thread.
227 */
228#define VM_ASSERT_OTHER_THREAD(pVM) \
229 AssertMsg(!VM_IS_EMT(pVM), ("Not other thread!!\n"))
230
231
232/** @def VM_ASSERT_STATE_RETURN
233 * Asserts a certain VM state.
234 */
235#define VM_ASSERT_STATE(pVM, _enmState) \
236 AssertMsg((pVM)->enmVMState == (_enmState), \
237 ("state %s, expected %s\n", VMGetStateName(pVM->enmVMState), VMGetStateName(_enmState)))
238
239/** @def VM_ASSERT_STATE_RETURN
240 * Asserts a certain VM state and returns if it doesn't match.
241 */
242#define VM_ASSERT_STATE_RETURN(pVM, _enmState, rc) \
243 AssertMsgReturn((pVM)->enmVMState == (_enmState), \
244 ("state %s, expected %s\n", VMGetStateName(pVM->enmVMState), VMGetStateName(_enmState)), \
245 (rc))
246
247
248
249
250/** This is the VM structure.
251 *
252 * It contains (nearly?) all the VM data which have to be available in all
253 * contexts. Even if it contains all the data the idea is to use APIs not
254 * to modify all the members all around the place. Therefore we make use of
255 * unions to hide everything which isn't local to the current source module.
256 * This means we'll have to pay a little bit of attention when adding new
257 * members to structures in the unions and make sure to keep the padding sizes
258 * up to date.
259 *
260 * Run tstVMStructSize after update!
261 */
262typedef struct VM
263{
264 /** The state of the VM.
265 * This field is read only to everyone except the VM and EM. */
266 VMSTATE enmVMState;
267 /** Forced action flags.
268 * See the VM_FF_* \#defines. Updated atomically.
269 */
270 volatile uint32_t fForcedActions;
271 /** Pointer to the array of page descriptors for the VM structure allocation. */
272 R3PTRTYPE(PSUPPAGE) paVMPagesR3;
273 /** Session handle. For use when calling SUPR0 APIs. */
274 PSUPDRVSESSION pSession;
275 /** Pointer to the ring-3 VM structure. */
276 PUVM pUVM;
277 /** Ring-3 Host Context VM Pointer. */
278 R3PTRTYPE(struct VM *) pVMR3;
279 /** Ring-0 Host Context VM Pointer. */
280 R0PTRTYPE(struct VM *) pVMR0;
281 /** Guest Context VM Pointer. */
282 GCPTRTYPE(struct VM *) pVMGC;
283
284 /** The GVM VM handle. Only the GVM should modify this field. */
285 uint32_t hSelf;
286 /** Reserved / padding. */
287 uint32_t u32Reserved;
288
289 /** @name Public VMM Switcher APIs
290 * @{ */
291 /**
292 * Assembly switch entry point for returning to host context.
293 * This function will clean up the stack frame.
294 *
295 * @param eax The return code, register.
296 * @param Ctx The guest core context.
297 * @remark Assume interrupts disabled.
298 */
299 RTGCPTR32 pfnVMMGCGuestToHostAsmGuestCtx/*(int32_t eax, CPUMCTXCORE Ctx)*/;
300
301 /**
302 * Assembly switch entry point for returning to host context.
303 *
304 * This is an alternative entry point which we'll be using when the we have the
305 * hypervisor context and need to save that before going to the host.
306 *
307 * This is typically useful when abandoning the hypervisor because of a trap
308 * and want the trap state to be saved.
309 *
310 * @param eax The return code, register.
311 * @param ecx Pointer to the hypervisor core context, register.
312 * @remark Assume interrupts disabled.
313 */
314 RTGCPTR32 pfnVMMGCGuestToHostAsmHyperCtx/*(int32_t eax, PCPUMCTXCORE ecx)*/;
315
316 /**
317 * Assembly switch entry point for returning to host context.
318 *
319 * This is an alternative to the two *Ctx APIs and implies that the context has already
320 * been saved, or that it's just a brief return to HC and that the caller intends to resume
321 * whatever it is doing upon 'return' from this call.
322 *
323 * @param eax The return code, register.
324 * @remark Assume interrupts disabled.
325 */
326 RTGCPTR32 pfnVMMGCGuestToHostAsm/*(int32_t eax)*/;
327 /** @} */
328
329
330 /** @name Various VM data owned by VM.
331 * @{ */
332 /** The thread handle of the emulation thread.
333 * Use the VM_IS_EMT() macro to check if executing in EMT. */
334 RTTHREAD ThreadEMT;
335 /** The native handle of ThreadEMT. Getting the native handle
336 * is generally faster than getting the IPRT one (except on OS/2 :-). */
337 RTNATIVETHREAD NativeThreadEMT;
338 /** @} */
339
340
341 /** @name Various items that are frequently accessed.
342 * @{ */
343 /** Raw ring-3 indicator. */
344 bool fRawR3Enabled;
345 /** Raw ring-0 indicator. */
346 bool fRawR0Enabled;
347 /** PATM enabled flag.
348 * This is placed here for performance reasons. */
349 bool fPATMEnabled;
350 /** CSAM enabled flag.
351 * This is placed here for performance reasons. */
352 bool fCSAMEnabled;
353
354 /** Hardware VM support is available and enabled.
355 * This is placed here for performance reasons. */
356 bool fHWACCMEnabled;
357 /** @} */
358
359
360 /* padding to make gnuc put the StatQemuToGC where msc does. */
361#if HC_ARCH_BITS == 32
362 uint32_t padding0;
363#endif
364
365 /** Profiling the total time from Qemu to GC. */
366 STAMPROFILEADV StatTotalQemuToGC;
367 /** Profiling the total time from GC to Qemu. */
368 STAMPROFILEADV StatTotalGCToQemu;
369 /** Profiling the total time spent in GC. */
370 STAMPROFILEADV StatTotalInGC;
371 /** Profiling the total time spent not in Qemu. */
372 STAMPROFILEADV StatTotalInQemu;
373 /** Profiling the VMMSwitcher code for going to GC. */
374 STAMPROFILEADV StatSwitcherToGC;
375 /** Profiling the VMMSwitcher code for going to HC. */
376 STAMPROFILEADV StatSwitcherToHC;
377 STAMPROFILEADV StatSwitcherSaveRegs;
378 STAMPROFILEADV StatSwitcherSysEnter;
379 STAMPROFILEADV StatSwitcherDebug;
380 STAMPROFILEADV StatSwitcherCR0;
381 STAMPROFILEADV StatSwitcherCR4;
382 STAMPROFILEADV StatSwitcherJmpCR3;
383 STAMPROFILEADV StatSwitcherRstrRegs;
384 STAMPROFILEADV StatSwitcherLgdt;
385 STAMPROFILEADV StatSwitcherLidt;
386 STAMPROFILEADV StatSwitcherLldt;
387 STAMPROFILEADV StatSwitcherTSS;
388
389 /* padding - the unions must be aligned on 32 bytes boundraries. */
390 uint32_t padding[HC_ARCH_BITS == 32 ? 4 : 6];
391
392 /** CPUM part. */
393 union
394 {
395#ifdef ___CPUMInternal_h
396 struct CPUM s;
397#endif
398 char padding[4384]; /* multiple of 32 */
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[1056]; /* 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 ? 1920 : 1952]; /* 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 ? 0x6f00 : 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