VirtualBox

source: vbox/trunk/include/VBox/vmm/vmapi.h@ 38838

Last change on this file since 38838 was 38838, checked in by vboxsync, 13 years ago

VMM,++: Try fix the async reset, suspend and power-off problems in PDM wrt conflicting VMM requests. Split them into priority requests and normal requests. The priority requests can safely be processed when PDM is doing async state change waits, the normal ones cannot. (The problem I bumped into was a unmap-chunk request from PGM being processed during PDMR3Reset, causing a recursive VMMR3EmtRendezvous deadlock.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.0 KB
Line 
1/** @file
2 * VM - The Virtual Machine, API.
3 */
4
5/*
6 * Copyright (C) 2006-2010 Oracle Corporation
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_vmm_vmapi_h
27#define ___VBox_vmm_vmapi_h
28
29#include <VBox/types.h>
30#include <VBox/vmm/stam.h>
31#include <VBox/vmm/cfgm.h>
32
33#include <iprt/stdarg.h>
34
35RT_C_DECLS_BEGIN
36
37/** @defgroup grp_vmm_apis VM All Contexts API
38 * @ingroup grp_vm
39 * @{ */
40
41/** @def VM_RC_ADDR
42 * Converts a current context address of data within the VM structure to the equivalent
43 * raw-mode address.
44 *
45 * @returns raw-mode virtual address.
46 * @param pVM Pointer to the VM.
47 * @param pvInVM CC Pointer within the VM.
48 */
49#ifdef IN_RING3
50# define VM_RC_ADDR(pVM, pvInVM) ( (RTRCPTR)((RTRCUINTPTR)pVM->pVMRC + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMR3)) )
51#elif defined(IN_RING0)
52# define VM_RC_ADDR(pVM, pvInVM) ( (RTRCPTR)((RTRCUINTPTR)pVM->pVMRC + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMR0)) )
53#else
54# define VM_RC_ADDR(pVM, pvInVM) ( (RTRCPTR)(pvInVM) )
55#endif
56
57/** @def VM_R3_ADDR
58 * Converts a current context address of data within the VM structure to the equivalent
59 * ring-3 host address.
60 *
61 * @returns host virtual address.
62 * @param pVM Pointer to the VM.
63 * @param pvInVM CC pointer within the VM.
64 */
65#ifdef IN_RC
66# define VM_R3_ADDR(pVM, pvInVM) ( (RTR3PTR)((RTR3UINTPTR)pVM->pVMR3 + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMRC)) )
67#elif defined(IN_RING0)
68# define VM_R3_ADDR(pVM, pvInVM) ( (RTR3PTR)((RTR3UINTPTR)pVM->pVMR3 + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMR0)) )
69#else
70# define VM_R3_ADDR(pVM, pvInVM) ( (RTR3PTR)(pvInVM) )
71#endif
72
73
74/** @def VM_R0_ADDR
75 * Converts a current context address of data within the VM structure to the equivalent
76 * ring-0 host address.
77 *
78 * @returns host virtual address.
79 * @param pVM Pointer to the VM.
80 * @param pvInVM CC pointer within the VM.
81 */
82#ifdef IN_RC
83# define VM_R0_ADDR(pVM, pvInVM) ( (RTR0PTR)((RTR0UINTPTR)pVM->pVMR0 + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMRC)) )
84#elif defined(IN_RING3)
85# define VM_R0_ADDR(pVM, pvInVM) ( (RTR0PTR)((RTR0UINTPTR)pVM->pVMR0 + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMR3)) )
86#else
87# define VM_R0_ADDR(pVM, pvInVM) ( (RTR0PTR)(pvInVM) )
88#endif
89
90
91
92/**
93 * VM error callback function.
94 *
95 * @param pVM The VM handle. Can be NULL if an error occurred before
96 * successfully creating a VM.
97 * @param pvUser The user argument.
98 * @param rc VBox status code.
99 * @param RT_SRC_POS_DECL The source position arguments. See RT_SRC_POS and RT_SRC_POS_ARGS.
100 * @param pszFormat Error message format string.
101 * @param args Error message arguments.
102 */
103typedef DECLCALLBACK(void) FNVMATERROR(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszError, va_list args);
104/** Pointer to a VM error callback. */
105typedef FNVMATERROR *PFNVMATERROR;
106
107VMMDECL(int) VMSetError(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
108VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args);
109
110/** @def VM_SET_ERROR
111 * Macro for setting a simple VM error message.
112 * Don't use '%' in the message!
113 *
114 * @returns rc. Meaning you can do:
115 * @code
116 * return VM_SET_ERROR(pVM, VERR_OF_YOUR_CHOICE, "descriptive message");
117 * @endcode
118 * @param pVM VM handle.
119 * @param rc VBox status code.
120 * @param pszMessage Error message string.
121 * @thread Any
122 */
123#define VM_SET_ERROR(pVM, rc, pszMessage) (VMSetError(pVM, rc, RT_SRC_POS, pszMessage))
124
125
126/**
127 * VM runtime error callback function.
128 *
129 * See VMSetRuntimeError for the detailed description of parameters.
130 *
131 * @param pVM The VM handle.
132 * @param pvUser The user argument.
133 * @param fFlags The error flags.
134 * @param pszErrorId Error ID string.
135 * @param pszFormat Error message format string.
136 * @param va Error message arguments.
137 */
138typedef DECLCALLBACK(void) FNVMATRUNTIMEERROR(PVM pVM, void *pvUser, uint32_t fFlags, const char *pszErrorId,
139 const char *pszFormat, va_list va);
140/** Pointer to a VM runtime error callback. */
141typedef FNVMATRUNTIMEERROR *PFNVMATRUNTIMEERROR;
142
143VMMDECL(int) VMSetRuntimeError(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...);
144VMMDECL(int) VMSetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list args);
145
146/** @name VMSetRuntimeError fFlags
147 * When no flags are given the VM will continue running and it's up to the front
148 * end to take action on the error condition.
149 *
150 * @{ */
151/** The error is fatal.
152 * The VM is not in a state where it can be saved and will enter a state
153 * where it can no longer execute code. The caller <b>must</b> propagate status
154 * codes. */
155#define VMSETRTERR_FLAGS_FATAL RT_BIT_32(0)
156/** Suspend the VM after, or if possible before, raising the error on EMT. The
157 * caller <b>must</b> propagate status codes. */
158#define VMSETRTERR_FLAGS_SUSPEND RT_BIT_32(1)
159/** Don't wait for the EMT to handle the request.
160 * Only valid when on a worker thread and there is a high risk of a dead
161 * lock. Be careful not to flood the user with errors. */
162#define VMSETRTERR_FLAGS_NO_WAIT RT_BIT_32(2)
163/** @} */
164
165/**
166 * VM state callback function.
167 *
168 * You are not allowed to call any function which changes the VM state from a
169 * state callback, except VMR3Destroy().
170 *
171 * @param pVM The VM handle.
172 * @param enmState The new state.
173 * @param enmOldState The old state.
174 * @param pvUser The user argument.
175 */
176typedef DECLCALLBACK(void) FNVMATSTATE(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser);
177/** Pointer to a VM state callback. */
178typedef FNVMATSTATE *PFNVMATSTATE;
179
180VMMDECL(const char *) VMGetStateName(VMSTATE enmState);
181
182
183/**
184 * Request type.
185 */
186typedef enum VMREQTYPE
187{
188 /** Invalid request. */
189 VMREQTYPE_INVALID = 0,
190 /** VM: Internal. */
191 VMREQTYPE_INTERNAL,
192 /** Maximum request type (exclusive). Used for validation. */
193 VMREQTYPE_MAX
194} VMREQTYPE;
195
196/**
197 * Request state.
198 */
199typedef enum VMREQSTATE
200{
201 /** The state is invalid. */
202 VMREQSTATE_INVALID = 0,
203 /** The request have been allocated and is in the process of being filed. */
204 VMREQSTATE_ALLOCATED,
205 /** The request is queued by the requester. */
206 VMREQSTATE_QUEUED,
207 /** The request is begin processed. */
208 VMREQSTATE_PROCESSING,
209 /** The request is completed, the requester is begin notified. */
210 VMREQSTATE_COMPLETED,
211 /** The request packet is in the free chain. (The requester */
212 VMREQSTATE_FREE
213} VMREQSTATE;
214
215/**
216 * Request flags.
217 */
218typedef enum VMREQFLAGS
219{
220 /** The request returns a VBox status code. */
221 VMREQFLAGS_VBOX_STATUS = 0,
222 /** The request is a void request and have no status code. */
223 VMREQFLAGS_VOID = 1,
224 /** Return type mask. */
225 VMREQFLAGS_RETURN_MASK = 1,
226 /** Caller does not wait on the packet, EMT will free it. */
227 VMREQFLAGS_NO_WAIT = 2,
228 /** Poke the destination EMT(s) if executing guest code. Use with care. */
229 VMREQFLAGS_POKE = 4,
230 /** Priority request that can safely be processed while doing async
231 * suspend and power off. */
232 VMREQFLAGS_PRIORITY = 8
233} VMREQFLAGS;
234
235
236/**
237 * VM Request packet.
238 *
239 * This is used to request an action in the EMT. Usually the requester is
240 * another thread, but EMT can also end up being the requester in which case
241 * it's carried out synchronously.
242 */
243typedef struct VMREQ
244{
245 /** Pointer to the next request in the chain. */
246 struct VMREQ * volatile pNext;
247 /** Pointer to ring-3 VM structure which this request belongs to. */
248 PUVM pUVM;
249 /** Request state. */
250 volatile VMREQSTATE enmState;
251 /** VBox status code for the completed request. */
252 volatile int32_t iStatus;
253 /** Requester event sem.
254 * The request can use this event semaphore to wait/poll for completion
255 * of the request.
256 */
257 RTSEMEVENT EventSem;
258 /** Set if the event semaphore is clear. */
259 volatile bool fEventSemClear;
260 /** Flags, VMR3REQ_FLAGS_*. */
261 unsigned fFlags;
262 /** Request type. */
263 VMREQTYPE enmType;
264 /** Request destination. */
265 VMCPUID idDstCpu;
266 /** Request specific data. */
267 union VMREQ_U
268 {
269 /** VMREQTYPE_INTERNAL. */
270 struct
271 {
272 /** Pointer to the function to be called. */
273 PFNRT pfn;
274 /** Number of arguments. */
275 unsigned cArgs;
276 /** Array of arguments. */
277 uintptr_t aArgs[64];
278 } Internal;
279 } u;
280} VMREQ;
281/** Pointer to a VM request packet. */
282typedef VMREQ *PVMREQ;
283
284/** @} */
285
286
287#ifndef IN_RC
288/** @defgroup grp_vmm_apis_hc VM Host Context API
289 * @ingroup grp_vm
290 * @{ */
291
292/** @} */
293#endif
294
295
296#ifdef IN_RING3
297/** @defgroup grp_vmm_apis_r3 VM Host Context Ring 3 API
298 * This interface is a _draft_!
299 * @ingroup grp_vm
300 * @{ */
301
302/**
303 * Completion notification codes.
304 */
305typedef enum VMINITCOMPLETED
306{
307 /** The ring-3 init is completed. */
308 VMINITCOMPLETED_RING3 = 1,
309 /** The ring-0 init is completed. */
310 VMINITCOMPLETED_RING0,
311 /** The hardware accelerated virtualization init is completed.
312 * Used to make decisision depending on whether HWACCMIsEnabled(). */
313 VMINITCOMPLETED_HWACCM,
314 /** The GC init is completed. */
315 VMINITCOMPLETED_GC
316} VMINITCOMPLETED;
317
318
319VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVm2UserCbs,
320 PFNVMATERROR pfnVMAtError, void *pvUserVM,
321 PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM,
322 PVM *ppVM);
323VMMR3DECL(int) VMR3PowerOn(PVM pVM);
324VMMR3DECL(int) VMR3Suspend(PVM pVM);
325VMMR3DECL(int) VMR3Resume(PVM pVM);
326VMMR3DECL(int) VMR3Reset(PVM pVM);
327
328/**
329 * Progress callback.
330 * This will report the completion percentage of an operation.
331 *
332 * @returns VINF_SUCCESS.
333 * @returns Error code to cancel the operation with.
334 * @param pVM The VM handle.
335 * @param uPercent Completion percentage (0-100).
336 * @param pvUser User specified argument.
337 */
338typedef DECLCALLBACK(int) FNVMPROGRESS(PVM pVM, unsigned uPercent, void *pvUser);
339/** Pointer to a FNVMPROGRESS function. */
340typedef FNVMPROGRESS *PFNVMPROGRESS;
341
342VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended);
343VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended);
344VMMR3DECL(int) VMR3LoadFromFile(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser);
345VMMR3DECL(int) VMR3LoadFromStream(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
346 PFNVMPROGRESS pfnProgress, void *pvProgressUser);
347VMMR3DECL(int) VMR3PowerOff(PVM pVM);
348VMMR3DECL(int) VMR3Destroy(PVM pVM);
349VMMR3DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
350VMMR3DECL(PVM) VMR3EnumVMs(PVM pVMPrev);
351
352VMMR3DECL(PVM) VMR3GetVM(PUVM pUVM);
353VMMR3DECL(PUVM) VMR3GetUVM(PVM pVM);
354VMMR3DECL(uint32_t) VMR3RetainUVM(PUVM pUVM);
355VMMR3DECL(uint32_t) VMR3ReleaseUVM(PUVM pUVM);
356VMMR3DECL(const char *) VMR3GetName(PUVM pUVM);
357VMMR3DECL(PRTUUID) VMR3GetUuid(PUVM pUVM, PRTUUID pUuid);
358VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM);
359VMMR3DECL(VMSTATE) VMR3GetStateU(PUVM pUVM);
360VMMR3DECL(const char *) VMR3GetStateName(VMSTATE enmState);
361
362/**
363 * VM destruction callback.
364 * @param pVM The VM which is about to be destroyed.
365 * @param pvUser The user parameter specified at registration.
366 */
367typedef DECLCALLBACK(void) FNVMATDTOR(PVM pVM, void *pvUser);
368/** Pointer to a VM destruction callback. */
369typedef FNVMATDTOR *PFNVMATDTOR;
370
371VMMR3DECL(int) VMR3AtDtorRegister(PFNVMATDTOR pfnAtDtor, void *pvUser);
372VMMR3DECL(int) VMR3AtDtorDeregister(PFNVMATDTOR pfnAtDtor);
373VMMR3DECL(int) VMR3AtStateRegister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser);
374VMMR3DECL(int) VMR3AtStateDeregister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser);
375VMMR3DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM);
376VMMR3DECL(int) VMR3AtErrorRegister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
377VMMR3DECL(int) VMR3AtErrorRegisterU(PUVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
378VMMR3DECL(int) VMR3AtErrorDeregister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
379VMMR3DECL(void) VMR3SetErrorWorker(PVM pVM);
380VMMR3DECL(uint32_t) VMR3GetErrorCount(PVM pVM);
381VMMR3DECL(uint32_t) VMR3GetErrorCountU(PUVM pUVM);
382VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
383VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
384VMMR3DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM);
385VMMR3DECL(uint32_t) VMR3GetRuntimeErrorCount(PVM pVM);
386VMMR3DECL(int) VMR3ReqCall(PVM pVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
387VMMR3DECL(int) VMR3ReqCallU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
388VMMR3DECL(int) VMR3ReqCallVU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
389VMMR3DECL(int) VMR3ReqCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
390VMMR3DECL(int) VMR3ReqCallNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
391VMMR3DECL(int) VMR3ReqCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
392VMMR3DECL(int) VMR3ReqCallVoidNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
393VMMR3DECL(int) VMR3ReqPriorityCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
394VMMR3DECL(int) VMR3ReqPriorityCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
395VMMR3DECL(int) VMR3ReqAlloc(PVM pVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu);
396VMMR3DECL(int) VMR3ReqAllocU(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu);
397VMMR3DECL(int) VMR3ReqFree(PVMREQ pReq);
398VMMR3DECL(int) VMR3ReqQueue(PVMREQ pReq, RTMSINTERVAL cMillies);
399VMMR3DECL(int) VMR3ReqWait(PVMREQ pReq, RTMSINTERVAL cMillies);
400VMMR3DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPriorityOnly);
401VMMR3DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags);
402VMMR3DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags);
403/** @name Flags for VMR3NotifyCpuFFU and VMR3NotifyGlobalFFU.
404 * @{ */
405/** Whether we've done REM or not. */
406#define VMNOTIFYFF_FLAGS_DONE_REM RT_BIT_32(0)
407/** Whether we should poke the CPU if it's executing guest code. */
408#define VMNOTIFYFF_FLAGS_POKE RT_BIT_32(1)
409/** @} */
410
411VMMR3DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts);
412VMMR3DECL(int) VMR3WaitU(PUVMCPU pUVMCpu);
413VMMR3_INT_DECL(int) VMR3AsyncPdmNotificationWaitU(PUVMCPU pUVCpu);
414VMMR3_INT_DECL(void) VMR3AsyncPdmNotificationWakeupU(PUVM pUVM);
415VMMR3DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM);
416VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PVM pVM);
417VMMR3DECL(RTTHREAD) VMR3GetVMCPUThreadU(PUVM pUVM);
418VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThread(PVM pVM);
419VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThreadU(PUVM pUVM);
420VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage);
421VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu);
422VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu);
423VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, uint32_t uCpuExecutionCap);
424/** @} */
425#endif /* IN_RING3 */
426
427
428#ifdef IN_RC
429/** @defgroup grp_vmm_apis_gc VM Guest Context APIs
430 * @ingroup grp_vm
431 * @{ */
432
433/** @} */
434#endif
435
436RT_C_DECLS_END
437
438/** @} */
439
440#endif
441
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