VirtualBox

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

Last change on this file since 12573 was 12545, checked in by vboxsync, 17 years ago

Updates for per-cpu MMIO range registration. (APIC)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.8 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 /** Number of virtual CPUs. */
290 uint32_t cCPUs;
291 /** Current CPU id; @todo move to per CPU structure. */
292 uint32_t idCPU;
293 /** Reserved; alignment. */
294 uint32_t u32Reserved[7];
295
296 /** @name Public VMM Switcher APIs
297 * @{ */
298 /**
299 * Assembly switch entry point for returning to host context.
300 * This function will clean up the stack frame.
301 *
302 * @param eax The return code, register.
303 * @param Ctx The guest core context.
304 * @remark Assume interrupts disabled.
305 */
306 RTGCPTR32 pfnVMMGCGuestToHostAsmGuestCtx/*(int32_t eax, CPUMCTXCORE Ctx)*/;
307
308 /**
309 * Assembly switch entry point for returning to host context.
310 *
311 * This is an alternative entry point which we'll be using when the we have the
312 * hypervisor context and need to save that before going to the host.
313 *
314 * This is typically useful when abandoning the hypervisor because of a trap
315 * and want the trap state to be saved.
316 *
317 * @param eax The return code, register.
318 * @param ecx Pointer to the hypervisor core context, register.
319 * @remark Assume interrupts disabled.
320 */
321 RTGCPTR32 pfnVMMGCGuestToHostAsmHyperCtx/*(int32_t eax, PCPUMCTXCORE ecx)*/;
322
323 /**
324 * Assembly switch entry point for returning to host context.
325 *
326 * This is an alternative to the two *Ctx APIs and implies that the context has already
327 * been saved, or that it's just a brief return to HC and that the caller intends to resume
328 * whatever it is doing upon 'return' from this call.
329 *
330 * @param eax The return code, register.
331 * @remark Assume interrupts disabled.
332 */
333 RTGCPTR32 pfnVMMGCGuestToHostAsm/*(int32_t eax)*/;
334 /** @} */
335
336
337 /** @name Various VM data owned by VM.
338 * @{ */
339 /** The thread handle of the emulation thread.
340 * Use the VM_IS_EMT() macro to check if executing in EMT. */
341 RTTHREAD ThreadEMT;
342 /** The native handle of ThreadEMT. Getting the native handle
343 * is generally faster than getting the IPRT one (except on OS/2 :-). */
344 RTNATIVETHREAD NativeThreadEMT;
345 /** @} */
346
347
348 /** @name Various items that are frequently accessed.
349 * @{ */
350 /** Raw ring-3 indicator. */
351 bool fRawR3Enabled;
352 /** Raw ring-0 indicator. */
353 bool fRawR0Enabled;
354 /** PATM enabled flag.
355 * This is placed here for performance reasons. */
356 bool fPATMEnabled;
357 /** CSAM enabled flag.
358 * This is placed here for performance reasons. */
359 bool fCSAMEnabled;
360
361 /** Hardware VM support is available and enabled.
362 * This is placed here for performance reasons. */
363 bool fHWACCMEnabled;
364 /** @} */
365
366
367 /* padding to make gnuc put the StatQemuToGC where msc does. */
368#if HC_ARCH_BITS == 32
369 uint32_t padding0;
370#endif
371
372 /** Profiling the total time from Qemu to GC. */
373 STAMPROFILEADV StatTotalQemuToGC;
374 /** Profiling the total time from GC to Qemu. */
375 STAMPROFILEADV StatTotalGCToQemu;
376 /** Profiling the total time spent in GC. */
377 STAMPROFILEADV StatTotalInGC;
378 /** Profiling the total time spent not in Qemu. */
379 STAMPROFILEADV StatTotalInQemu;
380 /** Profiling the VMMSwitcher code for going to GC. */
381 STAMPROFILEADV StatSwitcherToGC;
382 /** Profiling the VMMSwitcher code for going to HC. */
383 STAMPROFILEADV StatSwitcherToHC;
384 STAMPROFILEADV StatSwitcherSaveRegs;
385 STAMPROFILEADV StatSwitcherSysEnter;
386 STAMPROFILEADV StatSwitcherDebug;
387 STAMPROFILEADV StatSwitcherCR0;
388 STAMPROFILEADV StatSwitcherCR4;
389 STAMPROFILEADV StatSwitcherJmpCR3;
390 STAMPROFILEADV StatSwitcherRstrRegs;
391 STAMPROFILEADV StatSwitcherLgdt;
392 STAMPROFILEADV StatSwitcherLidt;
393 STAMPROFILEADV StatSwitcherLldt;
394 STAMPROFILEADV StatSwitcherTSS;
395
396 /* padding - the unions must be aligned on 32 bytes boundraries. */
397 uint32_t padding[HC_ARCH_BITS == 32 ? 4 : 6];
398
399 /** CPUM part. */
400 union
401 {
402#ifdef ___CPUMInternal_h
403 struct CPUM s;
404#endif
405 char padding[4416]; /* multiple of 32 */
406 } cpum;
407
408 /** VMM part. */
409 union
410 {
411#ifdef ___VMMInternal_h
412 struct VMM s;
413#endif
414 char padding[1536]; /* multiple of 32 */
415 } vmm;
416
417 /** PGM part. */
418 union
419 {
420#ifdef ___PGMInternal_h
421 struct PGM s;
422#endif
423 char padding[50*1024]; /* multiple of 32 */
424 } pgm;
425
426 /** HWACCM part. */
427 union
428 {
429#ifdef ___HWACCMInternal_h
430 struct HWACCM s;
431#endif
432 char padding[1536]; /* multiple of 32 */
433 } hwaccm;
434
435 /** TRPM part. */
436 union
437 {
438#ifdef ___TRPMInternal_h
439 struct TRPM s;
440#endif
441 char padding[5344]; /* multiple of 32 */
442 } trpm;
443
444 /** SELM part. */
445 union
446 {
447#ifdef ___SELMInternal_h
448 struct SELM s;
449#endif
450 char padding[544]; /* multiple of 32 */
451 } selm;
452
453 /** MM part. */
454 union
455 {
456#ifdef ___MMInternal_h
457 struct MM s;
458#endif
459 char padding[128]; /* multiple of 32 */
460 } mm;
461
462 /** CFGM part. */
463 union
464 {
465#ifdef ___CFGMInternal_h
466 struct CFGM s;
467#endif
468 char padding[32]; /* multiple of 32 */
469 } cfgm;
470
471 /** PDM part. */
472 union
473 {
474#ifdef ___PDMInternal_h
475 struct PDM s;
476#endif
477 char padding[1056]; /* multiple of 32 */
478 } pdm;
479
480 /** IOM part. */
481 union
482 {
483#ifdef ___IOMInternal_h
484 struct IOM s;
485#endif
486 char padding[4544]; /* multiple of 32 */
487 } iom;
488
489 /** PATM part. */
490 union
491 {
492#ifdef ___PATMInternal_h
493 struct PATM s;
494#endif
495 char padding[768]; /* multiple of 32 */
496 } patm;
497
498 /** CSAM part. */
499 union
500 {
501#ifdef ___CSAMInternal_h
502 struct CSAM s;
503#endif
504 char padding[3328]; /* multiple of 32 */
505 } csam;
506
507 /** EM part. */
508 union
509 {
510#ifdef ___EMInternal_h
511 struct EM s;
512#endif
513 char padding[1344]; /* multiple of 32 */
514 } em;
515
516 /** TM part. */
517 union
518 {
519#ifdef ___TMInternal_h
520 struct TM s;
521#endif
522 char padding[1344]; /* multiple of 32 */
523 } tm;
524
525 /** DBGF part. */
526 union
527 {
528#ifdef ___DBGFInternal_h
529 struct DBGF s;
530#endif
531 char padding[2368]; /* multiple of 32 */
532 } dbgf;
533
534 /** SSM part. */
535 union
536 {
537#ifdef ___SSMInternal_h
538 struct SSM s;
539#endif
540 char padding[32]; /* multiple of 32 */
541 } ssm;
542
543 /** VM part. */
544 union
545 {
546#ifdef ___VMInternal_h
547 struct VMINT s;
548#endif
549 char padding[768]; /* multiple of 32 */
550 } vm;
551
552 /** REM part. */
553 union
554 {
555#ifdef ___REMInternal_h
556 struct REM s;
557#endif
558#if GC_ARCH_BITS == 32
559 char padding[HC_ARCH_BITS == 32 ? 0x6f00 : 0xbf00]; /* multiple of 32 */
560#else
561 char padding[HC_ARCH_BITS == 32 ? 0x9f00 : 0xdf00]; /* multiple of 32 */
562#endif
563 } rem;
564} VM;
565
566/** Pointer to a VM. */
567#ifndef ___VBox_types_h
568typedef struct VM *PVM;
569#endif
570
571
572#ifdef IN_GC
573__BEGIN_DECLS
574
575/** The VM structure.
576 * This is imported from the VMMGCBuiltin module, i.e. it's a one
577 * of those magic globals which we should avoid using.
578 */
579extern DECLIMPORT(VM) g_VM;
580
581__END_DECLS
582#endif
583
584/** @} */
585
586#endif
587
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette