VirtualBox

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

Last change on this file since 12064 was 12064, checked in by vboxsync, 16 years ago

More space for hwaccm

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.7 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/** REM needs to be informed about handler changes. */
110#define VM_FF_REM_HANDLER_NOTIFY RT_BIT_32(29)
111
112/** Suspend the VM - debug only. */
113#define VM_FF_DEBUG_SUSPEND RT_BIT_32(31)
114
115/** Externally forced actions. Used to quit the idle/wait loop. */
116#define VM_FF_EXTERNAL_SUSPENDED_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_REQUEST)
117/** Externally forced actions. Used to quit the idle/wait loop. */
118#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)
119/** High priority pre-execution actions. */
120#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 \
121 | 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)
122/** High priority pre raw-mode execution mask. */
123#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 \
124 | VM_FF_INHIBIT_INTERRUPTS)
125/** High priority post-execution actions. */
126#define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PDM_CRITSECT | VM_FF_CSAM_PENDING_ACTION)
127/** Normal priority post-execution actions. */
128#define VM_FF_NORMAL_PRIORITY_POST_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE)
129/** Normal priority actions. */
130#define VM_FF_NORMAL_PRIORITY_MASK (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY)
131/** Flags to check before resuming guest execution. */
132#define VM_FF_RESUME_GUEST_MASK (VM_FF_TO_R3)
133/** All the forced flags. */
134#define VM_FF_ALL_MASK (~0U)
135/** All the forced flags. */
136#define VM_FF_ALL_BUT_RAW_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_CSAM_PENDING_ACTION | VM_FF_PDM_CRITSECT))
137
138/** @} */
139
140/** @def VM_FF_SET
141 * Sets a force action flag.
142 *
143 * @param pVM VM Handle.
144 * @param fFlag The flag to set.
145 */
146#if 1
147# define VM_FF_SET(pVM, fFlag) ASMAtomicOrU32(&(pVM)->fForcedActions, (fFlag))
148#else
149# define VM_FF_SET(pVM, fFlag) \
150 do { ASMAtomicOrU32(&(pVM)->fForcedActions, (fFlag)); \
151 RTLogPrintf("VM_FF_SET : %08x %s - %s(%d) %s\n", (pVM)->fForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
152 } while (0)
153#endif
154
155/** @def VM_FF_CLEAR
156 * Clears a force action flag.
157 *
158 * @param pVM VM Handle.
159 * @param fFlag The flag to clear.
160 */
161#if 1
162# define VM_FF_CLEAR(pVM, fFlag) ASMAtomicAndU32(&(pVM)->fForcedActions, ~(fFlag))
163#else
164# define VM_FF_CLEAR(pVM, fFlag) \
165 do { ASMAtomicAndU32(&(pVM)->fForcedActions, ~(fFlag)); \
166 RTLogPrintf("VM_FF_CLEAR: %08x %s - %s(%d) %s\n", (pVM)->fForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
167 } while (0)
168#endif
169
170/** @def VM_FF_ISSET
171 * Checks if a force action flag is set.
172 *
173 * @param pVM VM Handle.
174 * @param fFlag The flag to check.
175 */
176#define VM_FF_ISSET(pVM, fFlag) (((pVM)->fForcedActions & (fFlag)) == (fFlag))
177
178/** @def VM_FF_ISPENDING
179 * Checks if one or more force action in the specified set is pending.
180 *
181 * @param pVM VM Handle.
182 * @param fFlags The flags to check for.
183 */
184#define VM_FF_ISPENDING(pVM, fFlags) ((pVM)->fForcedActions & (fFlags))
185
186
187/** @def VM_IS_EMT
188 * Checks if the current thread is the emulation thread (EMT).
189 *
190 * @remark The ring-0 variation will need attention if we expand the ring-0
191 * code to let threads other than EMT mess around with the VM.
192 */
193#ifdef IN_GC
194# define VM_IS_EMT(pVM) true
195#elif defined(IN_RING0)
196# define VM_IS_EMT(pVM) true
197#else
198# define VM_IS_EMT(pVM) ((pVM)->NativeThreadEMT == RTThreadNativeSelf())
199#endif
200
201/** @def VM_ASSERT_EMT
202 * Asserts that the current thread IS the emulation thread (EMT).
203 */
204#ifdef IN_GC
205# define VM_ASSERT_EMT(pVM) Assert(VM_IS_EMT(pVM))
206#elif defined(IN_RING0)
207# define VM_ASSERT_EMT(pVM) Assert(VM_IS_EMT(pVM))
208#else
209# define VM_ASSERT_EMT(pVM) \
210 AssertMsg(VM_IS_EMT(pVM), \
211 ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd\n", RTThreadNativeSelf(), pVM->NativeThreadEMT))
212#endif
213
214/** @def VM_ASSERT_EMT_RETURN
215 * Asserts that the current thread IS the emulation thread (EMT) and returns if it isn't.
216 */
217#ifdef IN_GC
218# define VM_ASSERT_EMT_RETURN(pVM, rc) AssertReturn(VM_IS_EMT(pVM), (rc))
219#elif defined(IN_RING0)
220# define VM_ASSERT_EMT_RETURN(pVM, rc) AssertReturn(VM_IS_EMT(pVM), (rc))
221#else
222# define VM_ASSERT_EMT_RETURN(pVM, rc) \
223 AssertMsgReturn(VM_IS_EMT(pVM), \
224 ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd\n", RTThreadNativeSelf(), pVM->NativeThreadEMT), \
225 (rc))
226#endif
227
228/**
229 * Asserts that the current thread is NOT the emulation thread.
230 */
231#define VM_ASSERT_OTHER_THREAD(pVM) \
232 AssertMsg(!VM_IS_EMT(pVM), ("Not other thread!!\n"))
233
234
235/** @def VM_ASSERT_STATE_RETURN
236 * Asserts a certain VM state.
237 */
238#define VM_ASSERT_STATE(pVM, _enmState) \
239 AssertMsg((pVM)->enmVMState == (_enmState), \
240 ("state %s, expected %s\n", VMGetStateName(pVM->enmVMState), VMGetStateName(_enmState)))
241
242/** @def VM_ASSERT_STATE_RETURN
243 * Asserts a certain VM state and returns if it doesn't match.
244 */
245#define VM_ASSERT_STATE_RETURN(pVM, _enmState, rc) \
246 AssertMsgReturn((pVM)->enmVMState == (_enmState), \
247 ("state %s, expected %s\n", VMGetStateName(pVM->enmVMState), VMGetStateName(_enmState)), \
248 (rc))
249
250
251
252
253/** This is the VM structure.
254 *
255 * It contains (nearly?) all the VM data which have to be available in all
256 * contexts. Even if it contains all the data the idea is to use APIs not
257 * to modify all the members all around the place. Therefore we make use of
258 * unions to hide everything which isn't local to the current source module.
259 * This means we'll have to pay a little bit of attention when adding new
260 * members to structures in the unions and make sure to keep the padding sizes
261 * up to date.
262 *
263 * Run tstVMStructSize after update!
264 */
265typedef struct VM
266{
267 /** The state of the VM.
268 * This field is read only to everyone except the VM and EM. */
269 VMSTATE enmVMState;
270 /** Forced action flags.
271 * See the VM_FF_* \#defines. Updated atomically.
272 */
273 volatile uint32_t fForcedActions;
274 /** Pointer to the array of page descriptors for the VM structure allocation. */
275 R3PTRTYPE(PSUPPAGE) paVMPagesR3;
276 /** Session handle. For use when calling SUPR0 APIs. */
277 PSUPDRVSESSION pSession;
278 /** Pointer to the ring-3 VM structure. */
279 PUVM pUVM;
280 /** Ring-3 Host Context VM Pointer. */
281 R3PTRTYPE(struct VM *) pVMR3;
282 /** Ring-0 Host Context VM Pointer. */
283 R0PTRTYPE(struct VM *) pVMR0;
284 /** Guest Context VM Pointer. */
285 RCPTRTYPE(struct VM *) pVMGC;
286
287 /** The GVM VM handle. Only the GVM should modify this field. */
288 uint32_t hSelf;
289 /** Reserved / padding. */
290 uint32_t u32Reserved;
291
292 /** @name Public VMM Switcher APIs
293 * @{ */
294 /**
295 * Assembly switch entry point for returning to host context.
296 * This function will clean up the stack frame.
297 *
298 * @param eax The return code, register.
299 * @param Ctx The guest core context.
300 * @remark Assume interrupts disabled.
301 */
302 RTGCPTR32 pfnVMMGCGuestToHostAsmGuestCtx/*(int32_t eax, CPUMCTXCORE Ctx)*/;
303
304 /**
305 * Assembly switch entry point for returning to host context.
306 *
307 * This is an alternative entry point which we'll be using when the we have the
308 * hypervisor context and need to save that before going to the host.
309 *
310 * This is typically useful when abandoning the hypervisor because of a trap
311 * and want the trap state to be saved.
312 *
313 * @param eax The return code, register.
314 * @param ecx Pointer to the hypervisor core context, register.
315 * @remark Assume interrupts disabled.
316 */
317 RTGCPTR32 pfnVMMGCGuestToHostAsmHyperCtx/*(int32_t eax, PCPUMCTXCORE ecx)*/;
318
319 /**
320 * Assembly switch entry point for returning to host context.
321 *
322 * This is an alternative to the two *Ctx APIs and implies that the context has already
323 * been saved, or that it's just a brief return to HC and that the caller intends to resume
324 * whatever it is doing upon 'return' from this call.
325 *
326 * @param eax The return code, register.
327 * @remark Assume interrupts disabled.
328 */
329 RTGCPTR32 pfnVMMGCGuestToHostAsm/*(int32_t eax)*/;
330 /** @} */
331
332
333 /** @name Various VM data owned by VM.
334 * @{ */
335 /** The thread handle of the emulation thread.
336 * Use the VM_IS_EMT() macro to check if executing in EMT. */
337 RTTHREAD ThreadEMT;
338 /** The native handle of ThreadEMT. Getting the native handle
339 * is generally faster than getting the IPRT one (except on OS/2 :-). */
340 RTNATIVETHREAD NativeThreadEMT;
341 /** @} */
342
343
344 /** @name Various items that are frequently accessed.
345 * @{ */
346 /** Raw ring-3 indicator. */
347 bool fRawR3Enabled;
348 /** Raw ring-0 indicator. */
349 bool fRawR0Enabled;
350 /** PATM enabled flag.
351 * This is placed here for performance reasons. */
352 bool fPATMEnabled;
353 /** CSAM enabled flag.
354 * This is placed here for performance reasons. */
355 bool fCSAMEnabled;
356
357 /** Hardware VM support is available and enabled.
358 * This is placed here for performance reasons. */
359 bool fHWACCMEnabled;
360 /** @} */
361
362
363 /* padding to make gnuc put the StatQemuToGC where msc does. */
364#if HC_ARCH_BITS == 32
365 uint32_t padding0;
366#endif
367
368 /** Profiling the total time from Qemu to GC. */
369 STAMPROFILEADV StatTotalQemuToGC;
370 /** Profiling the total time from GC to Qemu. */
371 STAMPROFILEADV StatTotalGCToQemu;
372 /** Profiling the total time spent in GC. */
373 STAMPROFILEADV StatTotalInGC;
374 /** Profiling the total time spent not in Qemu. */
375 STAMPROFILEADV StatTotalInQemu;
376 /** Profiling the VMMSwitcher code for going to GC. */
377 STAMPROFILEADV StatSwitcherToGC;
378 /** Profiling the VMMSwitcher code for going to HC. */
379 STAMPROFILEADV StatSwitcherToHC;
380 STAMPROFILEADV StatSwitcherSaveRegs;
381 STAMPROFILEADV StatSwitcherSysEnter;
382 STAMPROFILEADV StatSwitcherDebug;
383 STAMPROFILEADV StatSwitcherCR0;
384 STAMPROFILEADV StatSwitcherCR4;
385 STAMPROFILEADV StatSwitcherJmpCR3;
386 STAMPROFILEADV StatSwitcherRstrRegs;
387 STAMPROFILEADV StatSwitcherLgdt;
388 STAMPROFILEADV StatSwitcherLidt;
389 STAMPROFILEADV StatSwitcherLldt;
390 STAMPROFILEADV StatSwitcherTSS;
391
392 /* padding - the unions must be aligned on 32 bytes boundraries. */
393 uint32_t padding[HC_ARCH_BITS == 32 ? 4 : 6];
394
395 /** CPUM part. */
396 union
397 {
398#ifdef ___CPUMInternal_h
399 struct CPUM s;
400#endif
401 char padding[4416]; /* multiple of 32 */
402 } cpum;
403
404 /** VMM part. */
405 union
406 {
407#ifdef ___VMMInternal_h
408 struct VMM s;
409#endif
410 char padding[1024]; /* multiple of 32 */
411 } vmm;
412
413 /** PGM part. */
414 union
415 {
416#ifdef ___PGMInternal_h
417 struct PGM s;
418#endif
419 char padding[50*1024]; /* multiple of 32 */
420 } pgm;
421
422 /** HWACCM part. */
423 union
424 {
425#ifdef ___HWACCMInternal_h
426 struct HWACCM s;
427#endif
428 char padding[1536]; /* multiple of 32 */
429 } hwaccm;
430
431 /** TRPM part. */
432 union
433 {
434#ifdef ___TRPMInternal_h
435 struct TRPM s;
436#endif
437 char padding[5344]; /* multiple of 32 */
438 } trpm;
439
440 /** SELM part. */
441 union
442 {
443#ifdef ___SELMInternal_h
444 struct SELM s;
445#endif
446 char padding[544]; /* multiple of 32 */
447 } selm;
448
449 /** MM part. */
450 union
451 {
452#ifdef ___MMInternal_h
453 struct MM s;
454#endif
455 char padding[128]; /* multiple of 32 */
456 } mm;
457
458 /** CFGM part. */
459 union
460 {
461#ifdef ___CFGMInternal_h
462 struct CFGM s;
463#endif
464 char padding[32]; /* multiple of 32 */
465 } cfgm;
466
467 /** PDM part. */
468 union
469 {
470#ifdef ___PDMInternal_h
471 struct PDM s;
472#endif
473 char padding[1056]; /* multiple of 32 */
474 } pdm;
475
476 /** IOM part. */
477 union
478 {
479#ifdef ___IOMInternal_h
480 struct IOM s;
481#endif
482 char padding[4544]; /* multiple of 32 */
483 } iom;
484
485 /** PATM part. */
486 union
487 {
488#ifdef ___PATMInternal_h
489 struct PATM s;
490#endif
491 char padding[768]; /* multiple of 32 */
492 } patm;
493
494 /** CSAM part. */
495 union
496 {
497#ifdef ___CSAMInternal_h
498 struct CSAM s;
499#endif
500 char padding[3328]; /* multiple of 32 */
501 } csam;
502
503 /** EM part. */
504 union
505 {
506#ifdef ___EMInternal_h
507 struct EM s;
508#endif
509 char padding[1344]; /* multiple of 32 */
510 } em;
511
512 /** TM part. */
513 union
514 {
515#ifdef ___TMInternal_h
516 struct TM s;
517#endif
518 char padding[1344]; /* multiple of 32 */
519 } tm;
520
521 /** DBGF part. */
522 union
523 {
524#ifdef ___DBGFInternal_h
525 struct DBGF s;
526#endif
527 char padding[2368]; /* multiple of 32 */
528 } dbgf;
529
530 /** SSM part. */
531 union
532 {
533#ifdef ___SSMInternal_h
534 struct SSM s;
535#endif
536 char padding[32]; /* multiple of 32 */
537 } ssm;
538
539 /** VM part. */
540 union
541 {
542#ifdef ___VMInternal_h
543 struct VMINT s;
544#endif
545 char padding[768]; /* multiple of 32 */
546 } vm;
547
548 /** REM part. */
549 union
550 {
551#ifdef ___REMInternal_h
552 struct REM s;
553#endif
554#if GC_ARCH_BITS == 32
555 char padding[HC_ARCH_BITS == 32 ? 0x6f00 : 0xbf00]; /* multiple of 32 */
556#else
557 char padding[HC_ARCH_BITS == 32 ? 0x9f00 : 0xdf00]; /* multiple of 32 */
558#endif
559 } rem;
560} VM;
561
562/** Pointer to a VM. */
563#ifndef ___VBox_types_h
564typedef struct VM *PVM;
565#endif
566
567
568#ifdef IN_GC
569__BEGIN_DECLS
570
571/** The VM structure.
572 * This is imported from the VMMGCBuiltin module, i.e. it's a one
573 * of those magic globals which we should avoid using.
574 */
575extern DECLIMPORT(VM) g_VM;
576
577__END_DECLS
578#endif
579
580/** @} */
581
582#endif
583
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