VirtualBox

source: vbox/trunk/src/VBox/VMM/VM.cpp@ 22834

Last change on this file since 22834 was 22792, checked in by vboxsync, 15 years ago

SSM: Live snapshot and migration coding.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 112.7 KB
Line 
1/* $Id: VM.cpp 22792 2009-09-04 18:38:32Z vboxsync $ */
2/** @file
3 * VM - Virtual Machine
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22/** @page pg_vm VM API
23 *
24 * This is the encapsulating bit. It provides the APIs that Main and VBoxBFE
25 * use to create a VMM instance for running a guest in. It also provides
26 * facilities for queuing request for execution in EMT (serialization purposes
27 * mostly) and for reporting error back to the VMM user (Main/VBoxBFE).
28 *
29 *
30 * @section sec_vm_design Design Critique / Things To Do
31 *
32 * In hindsight this component is a big design mistake, all this stuff really
33 * belongs in the VMM component. It just seemed like a kind of ok idea at a
34 * time when the VMM bit was a bit vague. 'VM' also happend to be the name of
35 * the per-VM instance structure (see vm.h), so it kind of made sense. However
36 * as it turned out, VMM(.cpp) is almost empty all it provides in ring-3 is some
37 * minor functionally and some "routing" services.
38 *
39 * Fixing this is just a matter of some more or less straight forward
40 * refactoring, the question is just when someone will get to it.
41 *
42 */
43
44/*******************************************************************************
45* Header Files *
46*******************************************************************************/
47#define LOG_GROUP LOG_GROUP_VM
48#include <VBox/cfgm.h>
49#include <VBox/vmm.h>
50#include <VBox/gvmm.h>
51#include <VBox/mm.h>
52#include <VBox/cpum.h>
53#include <VBox/selm.h>
54#include <VBox/trpm.h>
55#include <VBox/dbgf.h>
56#include <VBox/pgm.h>
57#include <VBox/pdmapi.h>
58#include <VBox/pdmcritsect.h>
59#include <VBox/em.h>
60#include <VBox/rem.h>
61#include <VBox/tm.h>
62#include <VBox/stam.h>
63#include <VBox/patm.h>
64#ifdef VBOX_WITH_VMI
65# include <VBox/parav.h>
66#endif
67#include <VBox/csam.h>
68#include <VBox/iom.h>
69#include <VBox/ssm.h>
70#include <VBox/hwaccm.h>
71#include "VMInternal.h"
72#include <VBox/vm.h>
73#include <VBox/uvm.h>
74
75#include <VBox/sup.h>
76#include <VBox/dbg.h>
77#include <VBox/err.h>
78#include <VBox/param.h>
79#include <VBox/log.h>
80#include <iprt/assert.h>
81#include <iprt/alloc.h>
82#include <iprt/asm.h>
83#include <iprt/env.h>
84#include <iprt/string.h>
85#include <iprt/time.h>
86#include <iprt/semaphore.h>
87#include <iprt/thread.h>
88
89
90/*******************************************************************************
91* Structures and Typedefs *
92*******************************************************************************/
93/**
94 * VM destruction callback registration record.
95 */
96typedef struct VMATDTOR
97{
98 /** Pointer to the next record in the list. */
99 struct VMATDTOR *pNext;
100 /** Pointer to the callback function. */
101 PFNVMATDTOR pfnAtDtor;
102 /** The user argument. */
103 void *pvUser;
104} VMATDTOR;
105/** Pointer to a VM destruction callback registration record. */
106typedef VMATDTOR *PVMATDTOR;
107
108
109/*******************************************************************************
110* Global Variables *
111*******************************************************************************/
112/** Pointer to the list of VMs. */
113static PUVM g_pUVMsHead = NULL;
114
115/** Pointer to the list of at VM destruction callbacks. */
116static PVMATDTOR g_pVMAtDtorHead = NULL;
117/** Lock the g_pVMAtDtorHead list. */
118#define VM_ATDTOR_LOCK() do { } while (0)
119/** Unlock the g_pVMAtDtorHead list. */
120#define VM_ATDTOR_UNLOCK() do { } while (0)
121
122
123/*******************************************************************************
124* Internal Functions *
125*******************************************************************************/
126static int vmR3CreateUVM(uint32_t cCPUs, PUVM *ppUVM);
127static int vmR3CreateU(PUVM pUVM, uint32_t cCPUs, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM);
128static int vmR3InitRing3(PVM pVM, PUVM pUVM);
129static int vmR3InitVMCpu(PVM pVM);
130static int vmR3InitRing0(PVM pVM);
131static int vmR3InitGC(PVM pVM);
132static int vmR3InitDoCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
133static DECLCALLBACK(size_t) vmR3LogPrefixCallback(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser);
134static DECLCALLBACK(int) vmR3PowerOn(PVM pVM);
135static DECLCALLBACK(int) vmR3Suspend(PVM pVM);
136static DECLCALLBACK(int) vmR3Resume(PVM pVM);
137static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser);
138static DECLCALLBACK(int) vmR3Load(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser);
139static DECLCALLBACK(int) vmR3PowerOff(PVM pVM);
140static void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait);
141static void vmR3AtDtor(PVM pVM);
142static int vmR3AtResetU(PUVM pUVM);
143static DECLCALLBACK(int) vmR3Reset(PVM pVM);
144static DECLCALLBACK(int) vmR3AtStateRegisterU(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser);
145static DECLCALLBACK(int) vmR3AtStateDeregisterU(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser);
146static DECLCALLBACK(int) vmR3AtErrorRegisterU(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser);
147static DECLCALLBACK(int) vmR3AtErrorDeregisterU(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser);
148static int vmR3SetErrorU(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
149static DECLCALLBACK(int) vmR3AtRuntimeErrorRegisterU(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
150static DECLCALLBACK(int) vmR3AtRuntimeErrorDeregisterU(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
151
152
153/**
154 * Do global VMM init.
155 *
156 * @returns VBox status code.
157 */
158VMMR3DECL(int) VMR3GlobalInit(void)
159{
160 /*
161 * Only once.
162 */
163 static bool volatile s_fDone = false;
164 if (s_fDone)
165 return VINF_SUCCESS;
166
167 /*
168 * We're done.
169 */
170 s_fDone = true;
171 return VINF_SUCCESS;
172}
173
174
175
176/**
177 * Creates a virtual machine by calling the supplied configuration constructor.
178 *
179 * On successful returned the VM is powered, i.e. VMR3PowerOn() should be
180 * called to start the execution.
181 *
182 * @returns 0 on success.
183 * @returns VBox error code on failure.
184 * @param cCPUs Number of virtual CPUs for the new VM.
185 * @param pfnVMAtError Pointer to callback function for setting VM
186 * errors. This was added as an implicit call to
187 * VMR3AtErrorRegister() since there is no way the
188 * caller can get to the VM handle early enough to
189 * do this on its own.
190 * This is called in the context of an EMT.
191 * @param pvUserVM The user argument passed to pfnVMAtError.
192 * @param pfnCFGMConstructor Pointer to callback function for constructing the VM configuration tree.
193 * This is called in the context of an EMT0.
194 * @param pvUserCFGM The user argument passed to pfnCFGMConstructor.
195 * @param ppVM Where to store the 'handle' of the created VM.
196 */
197VMMR3DECL(int) VMR3Create(uint32_t cCPUs, PFNVMATERROR pfnVMAtError, void *pvUserVM, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM, PVM *ppVM)
198{
199 LogFlow(("VMR3Create: cCPUs=%RU32 pfnVMAtError=%p pvUserVM=%p pfnCFGMConstructor=%p pvUserCFGM=%p ppVM=%p\n", cCPUs, pfnVMAtError, pvUserVM, pfnCFGMConstructor, pvUserCFGM, ppVM));
200
201 /*
202 * Because of the current hackiness of the applications
203 * we'll have to initialize global stuff from here.
204 * Later the applications will take care of this in a proper way.
205 */
206 static bool fGlobalInitDone = false;
207 if (!fGlobalInitDone)
208 {
209 int rc = VMR3GlobalInit();
210 if (RT_FAILURE(rc))
211 return rc;
212 fGlobalInitDone = true;
213 }
214
215 /*
216 * Validate input.
217 */
218 AssertLogRelMsgReturn(cCPUs > 0 && cCPUs <= VMM_MAX_CPU_COUNT, ("%RU32\n", cCPUs), VERR_TOO_MANY_CPUS);
219
220 /*
221 * Create the UVM so we can register the at-error callback
222 * and consoliate a bit of cleanup code.
223 */
224 PUVM pUVM = NULL; /* shuts up gcc */
225 int rc = vmR3CreateUVM(cCPUs, &pUVM);
226 if (RT_FAILURE(rc))
227 return rc;
228 if (pfnVMAtError)
229 rc = VMR3AtErrorRegisterU(pUVM, pfnVMAtError, pvUserVM);
230 if (RT_SUCCESS(rc))
231 {
232 /*
233 * Initialize the support library creating the session for this VM.
234 */
235 rc = SUPR3Init(&pUVM->vm.s.pSession);
236 if (RT_SUCCESS(rc))
237 {
238 /*
239 * Call vmR3CreateU in the EMT thread and wait for it to finish.
240 *
241 * Note! VMCPUID_ANY is used here because VMR3ReqQueueU would have trouble
242 * submitting a request to a specific VCPU without a pVM. So, to make
243 * sure init is running on EMT(0), vmR3EmulationThreadWithId makes sure
244 * that only EMT(0) is servicing VMCPUID_ANY requests when pVM is NULL.
245 */
246 PVMREQ pReq;
247 rc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)vmR3CreateU, 4,
248 pUVM, cCPUs, pfnCFGMConstructor, pvUserCFGM);
249 if (RT_SUCCESS(rc))
250 {
251 rc = pReq->iStatus;
252 VMR3ReqFree(pReq);
253 if (RT_SUCCESS(rc))
254 {
255 /*
256 * Success!
257 */
258 *ppVM = pUVM->pVM;
259 LogFlow(("VMR3Create: returns VINF_SUCCESS *ppVM=%p\n", *ppVM));
260 return VINF_SUCCESS;
261 }
262 }
263 else
264 AssertMsgFailed(("VMR3ReqCall failed rc=%Rrc\n", rc));
265
266 /*
267 * An error occurred during VM creation. Set the error message directly
268 * using the initial callback, as the callback list doesn't exist yet.
269 */
270 const char *pszError = NULL;
271 switch (rc)
272 {
273 case VERR_VMX_IN_VMX_ROOT_MODE:
274#ifdef RT_OS_LINUX
275 pszError = N_("VirtualBox can't operate in VMX root mode. "
276 "Please disable the KVM kernel extension, recompile your kernel and reboot");
277#else
278 pszError = N_("VirtualBox can't operate in VMX root mode. Please close all other virtualization programs.");
279#endif
280 break;
281
282 case VERR_VERSION_MISMATCH:
283 pszError = N_("VMMR0 driver version mismatch. Please terminate all VMs, make sure that "
284 "VBoxNetDHCP is not running and try again. If you still get this error, "
285 "re-install VirtualBox");
286 break;
287
288#ifdef RT_OS_LINUX
289 case VERR_SUPDRV_COMPONENT_NOT_FOUND:
290 pszError = N_("One of the kernel modules was not successfully loaded. Make sure "
291 "that no kernel modules from an older version of VirtualBox exist. "
292 "Then try to recompile and reload the kernel modules by executing "
293 "'/etc/init.d/vboxdrv setup' as root");
294 break;
295#endif
296
297 case VERR_RAW_MODE_INVALID_SMP:
298 pszError = N_("VT-x/AMD-V is either not available on your host or disabled. "
299 "VirtualBox requires this hardware extension to emulate more than one "
300 "guest CPU");
301 break;
302
303 case VERR_SUPDRV_KERNEL_TOO_OLD_FOR_VTX:
304#ifdef RT_OS_LINUX
305 pszError = N_("Because the host kernel is too old, VirtualBox cannot enable the VT-x "
306 "extension. Either upgrade your kernel to Linux 2.6.13 or later or disable "
307 "the VT-x extension in the VM settings. Note that without VT-x you have "
308 "to reduce the number of guest CPUs to one");
309#else
310 pszError = N_("Because the host kernel is too old, VirtualBox cannot enable the VT-x "
311 "extension. Either upgrade your kernel or disable the VT-x extension in the "
312 "VM settings. Note that without VT-x you have to reduce the number of guest "
313 "CPUs to one");
314#endif
315 break;
316
317 default:
318 pszError = N_("Unknown error creating VM");
319 break;
320 }
321 vmR3SetErrorU(pUVM, rc, RT_SRC_POS, pszError, rc);
322 }
323 else
324 {
325 /*
326 * An error occurred at support library initialization time (before the
327 * VM could be created). Set the error message directly using the
328 * initial callback, as the callback list doesn't exist yet.
329 */
330 const char *pszError;
331 switch (rc)
332 {
333 case VERR_VM_DRIVER_LOAD_ERROR:
334#ifdef RT_OS_LINUX
335 pszError = N_("VirtualBox kernel driver not loaded. The vboxdrv kernel module "
336 "was either not loaded or /dev/vboxdrv is not set up properly. "
337 "Re-setup the kernel module by executing "
338 "'/etc/init.d/vboxdrv setup' as root");
339#else
340 pszError = N_("VirtualBox kernel driver not loaded");
341#endif
342 break;
343 case VERR_VM_DRIVER_OPEN_ERROR:
344 pszError = N_("VirtualBox kernel driver cannot be opened");
345 break;
346 case VERR_VM_DRIVER_NOT_ACCESSIBLE:
347#ifdef VBOX_WITH_HARDENING
348 /* This should only happen if the executable wasn't hardened - bad code/build. */
349 pszError = N_("VirtualBox kernel driver not accessible, permission problem. "
350 "Re-install VirtualBox. If you are building it yourself, you "
351 "should make sure it installed correctly and that the setuid "
352 "bit is set on the executables calling VMR3Create.");
353#else
354 /* This should only happen when mixing builds or with the usual /dev/vboxdrv access issues. */
355# if defined(RT_OS_DARWIN)
356 pszError = N_("VirtualBox KEXT is not accessible, permission problem. "
357 "If you have built VirtualBox yourself, make sure that you do not "
358 "have the vboxdrv KEXT from a different build or installation loaded.");
359# elif defined(RT_OS_LINUX)
360 pszError = N_("VirtualBox kernel driver is not accessible, permission problem. "
361 "If you have built VirtualBox yourself, make sure that you do "
362 "not have the vboxdrv kernel module from a different build or "
363 "installation loaded. Also, make sure the vboxdrv udev rule gives "
364 "you the permission you need to access the device.");
365# elif defined(RT_OS_WINDOWS)
366 pszError = N_("VirtualBox kernel driver is not accessible, permission problem.");
367# else /* solaris, freebsd, ++. */
368 pszError = N_("VirtualBox kernel module is not accessible, permission problem. "
369 "If you have built VirtualBox yourself, make sure that you do "
370 "not have the vboxdrv kernel module from a different install loaded.");
371# endif
372#endif
373 break;
374 case VERR_INVALID_HANDLE: /** @todo track down and fix this error. */
375 case VERR_VM_DRIVER_NOT_INSTALLED:
376#ifdef RT_OS_LINUX
377 pszError = N_("VirtualBox kernel driver not installed. The vboxdrv kernel module "
378 "was either not loaded or /dev/vboxdrv was not created for some "
379 "reason. Re-setup the kernel module by executing "
380 "'/etc/init.d/vboxdrv setup' as root");
381#else
382 pszError = N_("VirtualBox kernel driver not installed");
383#endif
384 break;
385 case VERR_NO_MEMORY:
386 pszError = N_("VirtualBox support library out of memory");
387 break;
388 case VERR_VERSION_MISMATCH:
389 case VERR_VM_DRIVER_VERSION_MISMATCH:
390 pszError = N_("The VirtualBox support driver which is running is from a different "
391 "version of VirtualBox. You can correct this by stopping all "
392 "running instances of VirtualBox and reinstalling the software.");
393 break;
394 default:
395 pszError = N_("Unknown error initializing kernel driver");
396 AssertMsgFailed(("Add error message for rc=%d (%Rrc)\n", rc, rc));
397 }
398 vmR3SetErrorU(pUVM, rc, RT_SRC_POS, pszError, rc);
399 }
400 }
401
402 /* cleanup */
403 vmR3DestroyUVM(pUVM, 2000);
404 LogFlow(("VMR3Create: returns %Rrc\n", rc));
405 return rc;
406}
407
408
409/**
410 * Creates the UVM.
411 *
412 * This will not initialize the support library even if vmR3DestroyUVM
413 * will terminate that.
414 *
415 * @returns VBox status code.
416 * @param cCpus Number of virtual CPUs
417 * @param ppUVM Where to store the UVM pointer.
418 */
419static int vmR3CreateUVM(uint32_t cCpus, PUVM *ppUVM)
420{
421 uint32_t i;
422
423 /*
424 * Create and initialize the UVM.
425 */
426 PUVM pUVM = (PUVM)RTMemAllocZ(RT_OFFSETOF(UVM, aCpus[cCpus]));
427 AssertReturn(pUVM, VERR_NO_MEMORY);
428 pUVM->u32Magic = UVM_MAGIC;
429 pUVM->cCpus = cCpus;
430
431 AssertCompile(sizeof(pUVM->vm.s) <= sizeof(pUVM->vm.padding));
432
433 pUVM->vm.s.ppAtResetNext = &pUVM->vm.s.pAtReset;
434 pUVM->vm.s.ppAtStateNext = &pUVM->vm.s.pAtState;
435 pUVM->vm.s.ppAtErrorNext = &pUVM->vm.s.pAtError;
436 pUVM->vm.s.ppAtRuntimeErrorNext = &pUVM->vm.s.pAtRuntimeError;
437
438 pUVM->vm.s.enmHaltMethod = VMHALTMETHOD_BOOTSTRAP;
439
440 /* Initialize the VMCPU array in the UVM. */
441 for (i = 0; i < cCpus; i++)
442 {
443 pUVM->aCpus[i].pUVM = pUVM;
444 pUVM->aCpus[i].idCpu = i;
445 }
446
447 /* Allocate a TLS entry to store the VMINTUSERPERVMCPU pointer. */
448 int rc = RTTlsAllocEx(&pUVM->vm.s.idxTLS, NULL);
449 AssertRC(rc);
450 if (RT_SUCCESS(rc))
451 {
452 /* Allocate a halt method event semaphore for each VCPU. */
453 for (i = 0; i < cCpus; i++)
454 {
455 rc = RTSemEventCreate(&pUVM->aCpus[i].vm.s.EventSemWait);
456 if (RT_FAILURE(rc))
457 break;
458 }
459
460 if (RT_SUCCESS(rc))
461 {
462 /*
463 * Init fundamental (sub-)components - STAM, MMR3Heap and PDMLdr.
464 */
465 rc = STAMR3InitUVM(pUVM);
466 if (RT_SUCCESS(rc))
467 {
468 rc = MMR3InitUVM(pUVM);
469 if (RT_SUCCESS(rc))
470 {
471 rc = PDMR3InitUVM(pUVM);
472 if (RT_SUCCESS(rc))
473 {
474 /*
475 * Start the emulation threads for all VMCPUs.
476 */
477 for (i = 0; i < cCpus; i++)
478 {
479 rc = RTThreadCreateF(&pUVM->aCpus[i].vm.s.ThreadEMT, vmR3EmulationThread, &pUVM->aCpus[i], _1M,
480 RTTHREADTYPE_EMULATION, RTTHREADFLAGS_WAITABLE,
481 cCpus > 1 ? "EMT-%u" : "EMT", i);
482 if (RT_FAILURE(rc))
483 break;
484
485 pUVM->aCpus[i].vm.s.NativeThreadEMT = RTThreadGetNative(pUVM->aCpus[i].vm.s.ThreadEMT);
486 }
487
488 if (RT_SUCCESS(rc))
489 {
490 *ppUVM = pUVM;
491 return VINF_SUCCESS;
492 }
493
494 /* bail out. */
495 while (i-- > 0)
496 {
497 /** @todo rainy day: terminate the EMTs. */
498 }
499 PDMR3TermUVM(pUVM);
500 }
501 MMR3TermUVM(pUVM);
502 }
503 STAMR3TermUVM(pUVM);
504 }
505 for (i = 0; i < cCpus; i++)
506 {
507 RTSemEventDestroy(pUVM->aCpus[i].vm.s.EventSemWait);
508 pUVM->aCpus[i].vm.s.EventSemWait = NIL_RTSEMEVENT;
509 }
510 }
511 RTTlsFree(pUVM->vm.s.idxTLS);
512 }
513 RTMemFree(pUVM);
514 return rc;
515}
516
517
518/**
519 * Creates and initializes the VM.
520 *
521 * @thread EMT
522 */
523static int vmR3CreateU(PUVM pUVM, uint32_t cCpus, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM)
524{
525 int rc = VINF_SUCCESS;
526
527 /*
528 * Load the VMMR0.r0 module so that we can call GVMMR0CreateVM.
529 */
530 rc = PDMR3LdrLoadVMMR0U(pUVM);
531 if (RT_FAILURE(rc))
532 {
533 /** @todo we need a cleaner solution for this (VERR_VMX_IN_VMX_ROOT_MODE).
534 * bird: what about moving the message down here? Main picks the first message, right? */
535 if (rc == VERR_VMX_IN_VMX_ROOT_MODE)
536 return rc; /* proper error message set later on */
537 return vmR3SetErrorU(pUVM, rc, RT_SRC_POS, N_("Failed to load VMMR0.r0"));
538 }
539
540 /*
541 * Request GVMM to create a new VM for us.
542 */
543 GVMMCREATEVMREQ CreateVMReq;
544 CreateVMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
545 CreateVMReq.Hdr.cbReq = sizeof(CreateVMReq);
546 CreateVMReq.pSession = pUVM->vm.s.pSession;
547 CreateVMReq.pVMR0 = NIL_RTR0PTR;
548 CreateVMReq.pVMR3 = NULL;
549 CreateVMReq.cCpus = cCpus;
550 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_GVMM_CREATE_VM, 0, &CreateVMReq.Hdr);
551 if (RT_SUCCESS(rc))
552 {
553 PVM pVM = pUVM->pVM = CreateVMReq.pVMR3;
554 AssertRelease(VALID_PTR(pVM));
555 AssertRelease(pVM->pVMR0 == CreateVMReq.pVMR0);
556 AssertRelease(pVM->pSession == pUVM->vm.s.pSession);
557 AssertRelease(pVM->cCPUs == cCpus);
558 AssertRelease(pVM->offVMCPU == RT_UOFFSETOF(VM, aCpus));
559
560 Log(("VMR3Create: Created pUVM=%p pVM=%p pVMR0=%p hSelf=%#x cCPUs=%RU32\n",
561 pUVM, pVM, pVM->pVMR0, pVM->hSelf, pVM->cCPUs));
562
563 /*
564 * Initialize the VM structure and our internal data (VMINT).
565 */
566 pVM->pUVM = pUVM;
567
568 for (uint32_t i = 0; i < pVM->cCPUs; i++)
569 {
570 pVM->aCpus[i].pUVCpu = &pUVM->aCpus[i];
571 pVM->aCpus[i].idCpu = i;
572 pVM->aCpus[i].hNativeThread = pUVM->aCpus[i].vm.s.NativeThreadEMT;
573 Assert(pVM->aCpus[i].hNativeThread != NIL_RTNATIVETHREAD);
574
575 pUVM->aCpus[i].pVCpu = &pVM->aCpus[i];
576 pUVM->aCpus[i].pVM = pVM;
577 }
578
579
580 /*
581 * Init the configuration.
582 */
583 rc = CFGMR3Init(pVM, pfnCFGMConstructor, pvUserCFGM);
584 if (RT_SUCCESS(rc))
585 {
586 rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "HwVirtExtForced", &pVM->fHwVirtExtForced, false);
587 if (RT_SUCCESS(rc) && pVM->fHwVirtExtForced)
588 pVM->fHWACCMEnabled = true;
589
590 /*
591 * If executing in fake suplib mode disable RR3 and RR0 in the config.
592 */
593 const char *psz = RTEnvGet("VBOX_SUPLIB_FAKE");
594 if (psz && !strcmp(psz, "fake"))
595 {
596 CFGMR3RemoveValue(CFGMR3GetRoot(pVM), "RawR3Enabled");
597 CFGMR3InsertInteger(CFGMR3GetRoot(pVM), "RawR3Enabled", 0);
598 CFGMR3RemoveValue(CFGMR3GetRoot(pVM), "RawR0Enabled");
599 CFGMR3InsertInteger(CFGMR3GetRoot(pVM), "RawR0Enabled", 0);
600 }
601
602 /*
603 * Make sure the CPU count in the config data matches.
604 */
605 if (RT_SUCCESS(rc))
606 {
607 uint32_t cCPUsCfg;
608 rc = CFGMR3QueryU32Def(CFGMR3GetRoot(pVM), "NumCPUs", &cCPUsCfg, 1);
609 AssertLogRelMsgRC(rc, ("Configuration error: Querying \"NumCPUs\" as integer failed, rc=%Rrc\n", rc));
610 if (RT_SUCCESS(rc) && cCPUsCfg != cCpus)
611 {
612 AssertLogRelMsgFailed(("Configuration error: \"NumCPUs\"=%RU32 and VMR3CreateVM::cCPUs=%RU32 does not match!\n",
613 cCPUsCfg, cCpus));
614 rc = VERR_INVALID_PARAMETER;
615 }
616 }
617 if (RT_SUCCESS(rc))
618 {
619 /*
620 * Init the ring-3 components and ring-3 per cpu data, finishing it off
621 * by a relocation round (intermediate context finalization will do this).
622 */
623 rc = vmR3InitRing3(pVM, pUVM);
624 if (RT_SUCCESS(rc))
625 {
626 rc = vmR3InitVMCpu(pVM);
627 if (RT_SUCCESS(rc))
628 rc = PGMR3FinalizeMappings(pVM);
629 if (RT_SUCCESS(rc))
630 {
631
632 LogFlow(("Ring-3 init succeeded\n"));
633
634 /*
635 * Init the Ring-0 components.
636 */
637 rc = vmR3InitRing0(pVM);
638 if (RT_SUCCESS(rc))
639 {
640 /* Relocate again, because some switcher fixups depends on R0 init results. */
641 VMR3Relocate(pVM, 0);
642
643#ifdef VBOX_WITH_DEBUGGER
644 /*
645 * Init the tcp debugger console if we're building
646 * with debugger support.
647 */
648 void *pvUser = NULL;
649 rc = DBGCTcpCreate(pVM, &pvUser);
650 if ( RT_SUCCESS(rc)
651 || rc == VERR_NET_ADDRESS_IN_USE)
652 {
653 pUVM->vm.s.pvDBGC = pvUser;
654#endif
655 /*
656 * Init the Guest Context components.
657 */
658 rc = vmR3InitGC(pVM);
659 if (RT_SUCCESS(rc))
660 {
661 /*
662 * Now we can safely set the VM halt method to default.
663 */
664 rc = vmR3SetHaltMethodU(pUVM, VMHALTMETHOD_DEFAULT);
665 if (RT_SUCCESS(rc))
666 {
667 /*
668 * Set the state and link into the global list.
669 */
670 vmR3SetState(pVM, VMSTATE_CREATED);
671 pUVM->pNext = g_pUVMsHead;
672 g_pUVMsHead = pUVM;
673
674#ifdef LOG_ENABLED
675 RTLogSetCustomPrefixCallback(NULL, vmR3LogPrefixCallback, pUVM);
676#endif
677 return VINF_SUCCESS;
678 }
679 }
680#ifdef VBOX_WITH_DEBUGGER
681 DBGCTcpTerminate(pVM, pUVM->vm.s.pvDBGC);
682 pUVM->vm.s.pvDBGC = NULL;
683 }
684#endif
685 //..
686 }
687 }
688 vmR3Destroy(pVM);
689 }
690 }
691 //..
692
693 /* Clean CFGM. */
694 int rc2 = CFGMR3Term(pVM);
695 AssertRC(rc2);
696 }
697
698 /*
699 * Drop all references to VM and the VMCPU structures, then
700 * tell GVMM to destroy the VM.
701 */
702 pUVM->pVM = NULL;
703 for (VMCPUID i = 0; i < pUVM->cCpus; i++)
704 {
705 pUVM->aCpus[i].pVM = NULL;
706 pUVM->aCpus[i].pVCpu = NULL;
707 }
708 Assert(pUVM->vm.s.enmHaltMethod == VMHALTMETHOD_BOOTSTRAP);
709
710 if (pUVM->cCpus > 1)
711 {
712 /* Poke the other EMTs since they may have stale pVM and pVCpu references
713 on the stack (see VMR3WaitU for instance) if they've been awakened after
714 VM creation. */
715 for (VMCPUID i = 1; i < pUVM->cCpus; i++)
716 VMR3NotifyCpuFFU(&pUVM->aCpus[i], 0);
717 RTThreadSleep(RT_MIN(100 + 25 *(pUVM->cCpus - 1), 500)); /* very sophisticated */
718 }
719
720 int rc2 = SUPR3CallVMMR0Ex(CreateVMReq.pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL);
721 AssertRC(rc2);
722 }
723 else
724 vmR3SetErrorU(pUVM, rc, RT_SRC_POS, N_("VM creation failed (GVMM)"));
725
726 LogFlow(("vmR3CreateU: returns %Rrc\n", rc));
727 return rc;
728}
729
730
731/**
732 * Register the calling EMT with GVM.
733 *
734 * @returns VBox status code.
735 * @param pVM The VM handle.
736 * @param idCpu The Virtual CPU ID.
737 */
738static DECLCALLBACK(int) vmR3RegisterEMT(PVM pVM, VMCPUID idCpu)
739{
740 Assert(VMMGetCpuId(pVM) == idCpu);
741 int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, idCpu, VMMR0_DO_GVMM_REGISTER_VMCPU, 0, NULL);
742 if (RT_FAILURE(rc))
743 LogRel(("idCpu=%u rc=%Rrc\n", idCpu, rc));
744 return rc;
745}
746
747
748/**
749 * Initializes all R3 components of the VM
750 */
751static int vmR3InitRing3(PVM pVM, PUVM pUVM)
752{
753 int rc;
754
755 /*
756 * Register the other EMTs with GVM.
757 */
758 for (VMCPUID idCpu = 1; idCpu < pVM->cCPUs; idCpu++)
759 {
760 PVMREQ pReq;
761 rc = VMR3ReqCallU(pUVM, idCpu, &pReq, RT_INDEFINITE_WAIT, 0 /*fFlags*/,
762 (PFNRT)vmR3RegisterEMT, 2, pVM, idCpu);
763 if (RT_SUCCESS(rc))
764 rc = pReq->iStatus;
765 VMR3ReqFree(pReq);
766 if (RT_FAILURE(rc))
767 return rc;
768 }
769
770 /*
771 * Init all R3 components, the order here might be important.
772 */
773 rc = MMR3Init(pVM);
774 if (RT_SUCCESS(rc))
775 {
776 STAM_REG(pVM, &pVM->StatTotalInGC, STAMTYPE_PROFILE_ADV, "/PROF/VM/InGC", STAMUNIT_TICKS_PER_CALL, "Profiling the total time spent in GC.");
777 STAM_REG(pVM, &pVM->StatSwitcherToGC, STAMTYPE_PROFILE_ADV, "/PROF/VM/SwitchToGC", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
778 STAM_REG(pVM, &pVM->StatSwitcherToHC, STAMTYPE_PROFILE_ADV, "/PROF/VM/SwitchToHC", STAMUNIT_TICKS_PER_CALL, "Profiling switching to HC.");
779 STAM_REG(pVM, &pVM->StatSwitcherSaveRegs, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/SaveRegs", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
780 STAM_REG(pVM, &pVM->StatSwitcherSysEnter, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/SysEnter", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
781 STAM_REG(pVM, &pVM->StatSwitcherDebug, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/Debug", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
782 STAM_REG(pVM, &pVM->StatSwitcherCR0, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/CR0", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
783 STAM_REG(pVM, &pVM->StatSwitcherCR4, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/CR4", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
784 STAM_REG(pVM, &pVM->StatSwitcherLgdt, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/Lgdt", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
785 STAM_REG(pVM, &pVM->StatSwitcherLidt, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/Lidt", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
786 STAM_REG(pVM, &pVM->StatSwitcherLldt, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/Lldt", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
787 STAM_REG(pVM, &pVM->StatSwitcherTSS, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/TSS", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
788 STAM_REG(pVM, &pVM->StatSwitcherJmpCR3, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/JmpCR3", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
789 STAM_REG(pVM, &pVM->StatSwitcherRstrRegs, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/RstrRegs", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
790
791 for (unsigned iCpu=0;iCpu<pVM->cCPUs;iCpu++)
792 {
793 rc = STAMR3RegisterF(pVM, &pUVM->aCpus[iCpu].vm.s.StatHaltYield, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling halted state yielding.", "/PROF/VM/CPU%d/Halt/Yield", iCpu);
794 AssertRC(rc);
795 rc = STAMR3RegisterF(pVM, &pUVM->aCpus[iCpu].vm.s.StatHaltBlock, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling halted state blocking.", "/PROF/VM/CPU%d/Halt/Block", iCpu);
796 AssertRC(rc);
797 rc = STAMR3RegisterF(pVM, &pUVM->aCpus[iCpu].vm.s.StatHaltTimers, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling halted state timer tasks.", "/PROF/VM/CPU%d/Halt/Timers", iCpu);
798 AssertRC(rc);
799 }
800
801 STAM_REG(pVM, &pUVM->vm.s.StatReqAllocNew, STAMTYPE_COUNTER, "/VM/Req/AllocNew", STAMUNIT_OCCURENCES, "Number of VMR3ReqAlloc returning a new packet.");
802 STAM_REG(pVM, &pUVM->vm.s.StatReqAllocRaces, STAMTYPE_COUNTER, "/VM/Req/AllocRaces", STAMUNIT_OCCURENCES, "Number of VMR3ReqAlloc causing races.");
803 STAM_REG(pVM, &pUVM->vm.s.StatReqAllocRecycled, STAMTYPE_COUNTER, "/VM/Req/AllocRecycled", STAMUNIT_OCCURENCES, "Number of VMR3ReqAlloc returning a recycled packet.");
804 STAM_REG(pVM, &pUVM->vm.s.StatReqFree, STAMTYPE_COUNTER, "/VM/Req/Free", STAMUNIT_OCCURENCES, "Number of VMR3ReqFree calls.");
805 STAM_REG(pVM, &pUVM->vm.s.StatReqFreeOverflow, STAMTYPE_COUNTER, "/VM/Req/FreeOverflow", STAMUNIT_OCCURENCES, "Number of times the request was actually freed.");
806
807 rc = CPUMR3Init(pVM);
808 if (RT_SUCCESS(rc))
809 {
810 rc = HWACCMR3Init(pVM);
811 if (RT_SUCCESS(rc))
812 {
813 rc = PGMR3Init(pVM);
814 if (RT_SUCCESS(rc))
815 {
816 rc = REMR3Init(pVM);
817 if (RT_SUCCESS(rc))
818 {
819 rc = MMR3InitPaging(pVM);
820 if (RT_SUCCESS(rc))
821 rc = TMR3Init(pVM);
822 if (RT_SUCCESS(rc))
823 {
824 rc = VMMR3Init(pVM);
825 if (RT_SUCCESS(rc))
826 {
827 rc = SELMR3Init(pVM);
828 if (RT_SUCCESS(rc))
829 {
830 rc = TRPMR3Init(pVM);
831 if (RT_SUCCESS(rc))
832 {
833 rc = CSAMR3Init(pVM);
834 if (RT_SUCCESS(rc))
835 {
836 rc = PATMR3Init(pVM);
837 if (RT_SUCCESS(rc))
838 {
839#ifdef VBOX_WITH_VMI
840 rc = PARAVR3Init(pVM);
841 if (RT_SUCCESS(rc))
842 {
843#endif
844 rc = IOMR3Init(pVM);
845 if (RT_SUCCESS(rc))
846 {
847 rc = EMR3Init(pVM);
848 if (RT_SUCCESS(rc))
849 {
850 rc = DBGFR3Init(pVM);
851 if (RT_SUCCESS(rc))
852 {
853 rc = PDMR3Init(pVM);
854 if (RT_SUCCESS(rc))
855 {
856 rc = PGMR3InitDynMap(pVM);
857 if (RT_SUCCESS(rc))
858 rc = MMR3HyperInitFinalize(pVM);
859 if (RT_SUCCESS(rc))
860 rc = PATMR3InitFinalize(pVM);
861 if (RT_SUCCESS(rc))
862 rc = PGMR3InitFinalize(pVM);
863 if (RT_SUCCESS(rc))
864 rc = SELMR3InitFinalize(pVM);
865 if (RT_SUCCESS(rc))
866 rc = TMR3InitFinalize(pVM);
867 if (RT_SUCCESS(rc))
868 rc = VMMR3InitFinalize(pVM);
869 if (RT_SUCCESS(rc))
870 rc = REMR3InitFinalize(pVM);
871 if (RT_SUCCESS(rc))
872 rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING3);
873 if (RT_SUCCESS(rc))
874 {
875 LogFlow(("vmR3InitRing3: returns %Rrc\n", VINF_SUCCESS));
876 return VINF_SUCCESS;
877 }
878 int rc2 = PDMR3Term(pVM);
879 AssertRC(rc2);
880 }
881 int rc2 = DBGFR3Term(pVM);
882 AssertRC(rc2);
883 }
884 int rc2 = EMR3Term(pVM);
885 AssertRC(rc2);
886 }
887 int rc2 = IOMR3Term(pVM);
888 AssertRC(rc2);
889 }
890#ifdef VBOX_WITH_VMI
891 int rc2 = PARAVR3Term(pVM);
892 AssertRC(rc2);
893 }
894#endif
895 int rc2 = PATMR3Term(pVM);
896 AssertRC(rc2);
897 }
898 int rc2 = CSAMR3Term(pVM);
899 AssertRC(rc2);
900 }
901 int rc2 = TRPMR3Term(pVM);
902 AssertRC(rc2);
903 }
904 int rc2 = SELMR3Term(pVM);
905 AssertRC(rc2);
906 }
907 int rc2 = VMMR3Term(pVM);
908 AssertRC(rc2);
909 }
910 int rc2 = TMR3Term(pVM);
911 AssertRC(rc2);
912 }
913 int rc2 = REMR3Term(pVM);
914 AssertRC(rc2);
915 }
916 int rc2 = PGMR3Term(pVM);
917 AssertRC(rc2);
918 }
919 int rc2 = HWACCMR3Term(pVM);
920 AssertRC(rc2);
921 }
922 //int rc2 = CPUMR3Term(pVM);
923 //AssertRC(rc2);
924 }
925 /* MMR3Term is not called here because it'll kill the heap. */
926 }
927
928 LogFlow(("vmR3InitRing3: returns %Rrc\n", rc));
929 return rc;
930}
931
932
933/**
934 * Initializes all VM CPU components of the VM
935 */
936static int vmR3InitVMCpu(PVM pVM)
937{
938 int rc = VINF_SUCCESS;
939 int rc2;
940
941 rc = CPUMR3InitCPU(pVM);
942 if (RT_SUCCESS(rc))
943 {
944 rc = HWACCMR3InitCPU(pVM);
945 if (RT_SUCCESS(rc))
946 {
947 rc = PGMR3InitCPU(pVM);
948 if (RT_SUCCESS(rc))
949 {
950 rc = TMR3InitCPU(pVM);
951 if (RT_SUCCESS(rc))
952 {
953 rc = VMMR3InitCPU(pVM);
954 if (RT_SUCCESS(rc))
955 {
956 rc = EMR3InitCPU(pVM);
957 if (RT_SUCCESS(rc))
958 {
959 LogFlow(("vmR3InitVMCpu: returns %Rrc\n", VINF_SUCCESS));
960 return VINF_SUCCESS;
961 }
962
963 rc2 = VMMR3TermCPU(pVM);
964 AssertRC(rc2);
965 }
966 rc2 = TMR3TermCPU(pVM);
967 AssertRC(rc2);
968 }
969 rc2 = PGMR3TermCPU(pVM);
970 AssertRC(rc2);
971 }
972 rc2 = HWACCMR3TermCPU(pVM);
973 AssertRC(rc2);
974 }
975 rc2 = CPUMR3TermCPU(pVM);
976 AssertRC(rc2);
977 }
978 LogFlow(("vmR3InitVMCpu: returns %Rrc\n", rc));
979 return rc;
980}
981
982
983/**
984 * Initializes all R0 components of the VM
985 */
986static int vmR3InitRing0(PVM pVM)
987{
988 LogFlow(("vmR3InitRing0:\n"));
989
990 /*
991 * Check for FAKE suplib mode.
992 */
993 int rc = VINF_SUCCESS;
994 const char *psz = RTEnvGet("VBOX_SUPLIB_FAKE");
995 if (!psz || strcmp(psz, "fake"))
996 {
997 /*
998 * Call the VMMR0 component and let it do the init.
999 */
1000 rc = VMMR3InitR0(pVM);
1001 }
1002 else
1003 Log(("vmR3InitRing0: skipping because of VBOX_SUPLIB_FAKE=fake\n"));
1004
1005 /*
1006 * Do notifications and return.
1007 */
1008 if (RT_SUCCESS(rc))
1009 rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING0);
1010
1011 /** todo: move this to the VMINITCOMPLETED_RING0 notification handler once implemented */
1012 if (RT_SUCCESS(rc))
1013 rc = HWACCMR3InitFinalizeR0(pVM);
1014
1015 LogFlow(("vmR3InitRing0: returns %Rrc\n", rc));
1016 return rc;
1017}
1018
1019
1020/**
1021 * Initializes all GC components of the VM
1022 */
1023static int vmR3InitGC(PVM pVM)
1024{
1025 LogFlow(("vmR3InitGC:\n"));
1026
1027 /*
1028 * Check for FAKE suplib mode.
1029 */
1030 int rc = VINF_SUCCESS;
1031 const char *psz = RTEnvGet("VBOX_SUPLIB_FAKE");
1032 if (!psz || strcmp(psz, "fake"))
1033 {
1034 /*
1035 * Call the VMMR0 component and let it do the init.
1036 */
1037 rc = VMMR3InitRC(pVM);
1038 }
1039 else
1040 Log(("vmR3InitGC: skipping because of VBOX_SUPLIB_FAKE=fake\n"));
1041
1042 /*
1043 * Do notifications and return.
1044 */
1045 if (RT_SUCCESS(rc))
1046 rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_GC);
1047 LogFlow(("vmR3InitGC: returns %Rrc\n", rc));
1048 return rc;
1049}
1050
1051
1052/**
1053 * Do init completed notifications.
1054 * This notifications can fail.
1055 *
1056 * @param pVM The VM handle.
1057 * @param enmWhat What's completed.
1058 */
1059static int vmR3InitDoCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
1060{
1061 return VINF_SUCCESS;
1062}
1063
1064
1065/**
1066 * Logger callback for inserting a custom prefix.
1067 *
1068 * @returns Number of chars written.
1069 * @param pLogger The logger.
1070 * @param pchBuf The output buffer.
1071 * @param cchBuf The output buffer size.
1072 * @param pvUser Pointer to the UVM structure.
1073 */
1074static DECLCALLBACK(size_t) vmR3LogPrefixCallback(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser)
1075{
1076 AssertReturn(cchBuf >= 2, 0);
1077 PUVM pUVM = (PUVM)pvUser;
1078 PUVMCPU pUVCpu = (PUVMCPU)RTTlsGet(pUVM->vm.s.idxTLS);
1079 if (pUVCpu)
1080 {
1081 static const char s_szHex[17] = "0123456789abcdef";
1082 VMCPUID const idCpu = pUVCpu->idCpu;
1083 pchBuf[1] = s_szHex[ idCpu & 15];
1084 pchBuf[0] = s_szHex[(idCpu >> 4) & 15];
1085 }
1086 else
1087 {
1088 pchBuf[0] = 'x';
1089 pchBuf[1] = 'y';
1090 }
1091
1092 return 2;
1093}
1094
1095
1096/**
1097 * Calls the relocation functions for all VMM components so they can update
1098 * any GC pointers. When this function is called all the basic VM members
1099 * have been updated and the actual memory relocation have been done
1100 * by the PGM/MM.
1101 *
1102 * This is used both on init and on runtime relocations.
1103 *
1104 * @param pVM VM handle.
1105 * @param offDelta Relocation delta relative to old location.
1106 */
1107VMMR3DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta)
1108{
1109 LogFlow(("VMR3Relocate: offDelta=%RGv\n", offDelta));
1110
1111 /*
1112 * The order here is very important!
1113 */
1114 PGMR3Relocate(pVM, offDelta);
1115 PDMR3LdrRelocateU(pVM->pUVM, offDelta);
1116 PGMR3Relocate(pVM, 0); /* Repeat after PDM relocation. */
1117 CPUMR3Relocate(pVM);
1118 HWACCMR3Relocate(pVM);
1119 SELMR3Relocate(pVM);
1120 VMMR3Relocate(pVM, offDelta);
1121 SELMR3Relocate(pVM); /* !hack! fix stack! */
1122 TRPMR3Relocate(pVM, offDelta);
1123 PATMR3Relocate(pVM);
1124 CSAMR3Relocate(pVM, offDelta);
1125 IOMR3Relocate(pVM, offDelta);
1126 EMR3Relocate(pVM);
1127 TMR3Relocate(pVM, offDelta);
1128 DBGFR3Relocate(pVM, offDelta);
1129 PDMR3Relocate(pVM, offDelta);
1130}
1131
1132
1133/**
1134 * Power on the virtual machine.
1135 *
1136 * @returns 0 on success.
1137 * @returns VBox error code on failure.
1138 * @param pVM VM to power on.
1139 * @thread Any thread.
1140 * @vmstate Created
1141 * @vmstateto Running
1142 */
1143VMMR3DECL(int) VMR3PowerOn(PVM pVM)
1144{
1145 LogFlow(("VMR3PowerOn: pVM=%p\n", pVM));
1146
1147 /*
1148 * Validate input.
1149 */
1150 if (!pVM)
1151 {
1152 AssertMsgFailed(("Invalid VM pointer\n"));
1153 return VERR_INVALID_PARAMETER;
1154 }
1155
1156 /*
1157 * Request the operation in EMT (in order as VCPU 0 does all the work)
1158 */
1159 PVMREQ pReq;
1160 int rc = VMR3ReqCall(pVM, VMCPUID_ALL, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3PowerOn, 1, pVM);
1161 if (RT_SUCCESS(rc))
1162 {
1163 rc = pReq->iStatus;
1164 VMR3ReqFree(pReq);
1165 }
1166
1167 LogFlow(("VMR3PowerOn: returns %Rrc\n", rc));
1168 return rc;
1169}
1170
1171
1172/**
1173 * Power on the virtual machine.
1174 *
1175 * @returns 0 on success.
1176 * @returns VBox error code on failure.
1177 * @param pVM VM to power on.
1178 * @thread EMT
1179 */
1180static DECLCALLBACK(int) vmR3PowerOn(PVM pVM)
1181{
1182 LogFlow(("vmR3PowerOn: pVM=%p\n", pVM));
1183
1184 /*
1185 * EMT(0) does the actual power on work *before* the other EMTs
1186 * get here, they just need to set their state to STARTED so they
1187 * get out of the EMT loop and into EM.
1188 */
1189 PVMCPU pVCpu = VMMGetCpu(pVM);
1190 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
1191 if (pVCpu->idCpu != 0)
1192 return VINF_SUCCESS;
1193
1194 /*
1195 * Validate input.
1196 */
1197 if (pVM->enmVMState != VMSTATE_CREATED)
1198 {
1199 AssertMsgFailed(("Invalid VM state %d\n", pVM->enmVMState));
1200 return VERR_VM_INVALID_VM_STATE;
1201 }
1202
1203 /*
1204 * Change the state, notify the components and resume the execution.
1205 */
1206 vmR3SetState(pVM, VMSTATE_RUNNING);
1207 PDMR3PowerOn(pVM);
1208
1209 return VINF_SUCCESS;
1210}
1211
1212
1213/**
1214 * Suspends a running VM.
1215 *
1216 * @returns 0 on success.
1217 * @returns VBox error code on failure.
1218 * @param pVM VM to suspend.
1219 * @thread Any thread.
1220 * @vmstate Running
1221 * @vmstateto Suspended
1222 */
1223VMMR3DECL(int) VMR3Suspend(PVM pVM)
1224{
1225 LogFlow(("VMR3Suspend: pVM=%p\n", pVM));
1226
1227 /*
1228 * Validate input.
1229 */
1230 if (!pVM)
1231 {
1232 AssertMsgFailed(("Invalid VM pointer\n"));
1233 return VERR_INVALID_PARAMETER;
1234 }
1235
1236 /*
1237 * Request the operation in EMT. (in reverse order as VCPU 0 does the actual work)
1238 */
1239 PVMREQ pReq = NULL;
1240 int rc = VMR3ReqCall(pVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Suspend, 1, pVM);
1241 if (RT_SUCCESS(rc))
1242 {
1243 rc = pReq->iStatus;
1244 VMR3ReqFree(pReq);
1245 }
1246 else
1247 Assert(pReq == NULL);
1248
1249 LogFlow(("VMR3Suspend: returns %Rrc\n", rc));
1250 return rc;
1251}
1252
1253
1254/**
1255 * Suspends a running VM and prevent state saving until the VM is resumed or stopped.
1256 *
1257 * @returns 0 on success.
1258 * @returns VBox error code on failure.
1259 * @param pVM VM to suspend.
1260 * @thread Any thread.
1261 * @vmstate Running
1262 * @vmstateto Suspended
1263 */
1264VMMR3DECL(int) VMR3SuspendNoSave(PVM pVM)
1265{
1266 pVM->vm.s.fPreventSaveState = true;
1267 return VMR3Suspend(pVM);
1268}
1269
1270
1271/**
1272 * Suspends a running VM.
1273 *
1274 * @returns 0 on success.
1275 * @returns VBox error code on failure.
1276 * @param pVM VM to suspend.
1277 * @thread EMT
1278 */
1279static DECLCALLBACK(int) vmR3Suspend(PVM pVM)
1280{
1281 LogFlow(("vmR3Suspend: pVM=%p\n", pVM));
1282
1283 /*
1284 * Validate input.
1285 */
1286 if (pVM->enmVMState != VMSTATE_RUNNING)
1287 {
1288 AssertMsgFailed(("Invalid VM state %d\n", pVM->enmVMState));
1289 return VERR_VM_INVALID_VM_STATE;
1290 }
1291
1292 PVMCPU pVCpu = VMMGetCpu(pVM);
1293 /* Only VCPU 0 does the actual work (*after* all the other CPUs has been here). */
1294 if (pVCpu->idCpu != 0)
1295 return VINF_EM_SUSPEND;
1296
1297 /*
1298 * Change the state, notify the components and resume the execution.
1299 */
1300 vmR3SetState(pVM, VMSTATE_SUSPENDED);
1301 PDMR3Suspend(pVM);
1302
1303 return VINF_EM_SUSPEND;
1304}
1305
1306
1307/**
1308 * Resume VM execution.
1309 *
1310 * @returns 0 on success.
1311 * @returns VBox error code on failure.
1312 * @param pVM The VM to resume.
1313 * @thread Any thread.
1314 * @vmstate Suspended
1315 * @vmstateto Running
1316 */
1317VMMR3DECL(int) VMR3Resume(PVM pVM)
1318{
1319 LogFlow(("VMR3Resume: pVM=%p\n", pVM));
1320
1321 /*
1322 * Validate input.
1323 */
1324 if (!pVM)
1325 {
1326 AssertMsgFailed(("Invalid VM pointer\n"));
1327 return VERR_INVALID_PARAMETER;
1328 }
1329
1330 /*
1331 * Request the operation in EMT. (in VCPU order as VCPU 0 does the actual work)
1332 */
1333 PVMREQ pReq = NULL;
1334 int rc = VMR3ReqCall(pVM, VMCPUID_ALL, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Resume, 1, pVM);
1335 if (RT_SUCCESS(rc))
1336 {
1337 rc = pReq->iStatus;
1338 VMR3ReqFree(pReq);
1339 }
1340 else
1341 Assert(pReq == NULL);
1342
1343 LogFlow(("VMR3Resume: returns %Rrc\n", rc));
1344 return rc;
1345}
1346
1347
1348/**
1349 * Resume VM execution.
1350 *
1351 * @returns 0 on success.
1352 * @returns VBox error code on failure.
1353 * @param pVM The VM to resume.
1354 * @thread EMT
1355 */
1356static DECLCALLBACK(int) vmR3Resume(PVM pVM)
1357{
1358 LogFlow(("vmR3Resume: pVM=%p\n", pVM));
1359
1360 PVMCPU pVCpu = VMMGetCpu(pVM);
1361 /* Only VCPU 0 does the actual work (*before* the others wake up). */
1362 if (pVCpu->idCpu != 0)
1363 return VINF_EM_RESUME;
1364
1365 /*
1366 * Validate input.
1367 */
1368 if (pVM->enmVMState != VMSTATE_SUSPENDED)
1369 {
1370 AssertMsgFailed(("Invalid VM state %d\n", pVM->enmVMState));
1371 return VERR_VM_INVALID_VM_STATE;
1372 }
1373
1374 /*
1375 * Change the state, notify the components and resume the execution.
1376 */
1377 pVM->vm.s.fPreventSaveState = false;
1378 vmR3SetState(pVM, VMSTATE_RUNNING);
1379 PDMR3Resume(pVM);
1380
1381 return VINF_EM_RESUME;
1382}
1383
1384
1385/**
1386 * Save current VM state.
1387 *
1388 * Can be used for both saving the state and creating snapshots.
1389 *
1390 * When called for a VM in the RUNNING state, the saved state is created live
1391 * and the VM is only suspended when the final part of the saving is preformed.
1392 * The VM state will not be restored to RUNNING in this case and it's up to the
1393 * caller to call VMR3Resume if this is desirable. (The rational is that the
1394 * caller probably wish to reconfigure the disks before resuming the VM.)
1395 *
1396 * @returns VBox status code.
1397 *
1398 * @param pVM VM which state should be saved.
1399 * @param pszFilename Name of the save state file.
1400 * @param fContinueAftewards Continue execution afterwards. When in doubt,
1401 * set this to true.
1402 * @param pfnProgress Progress callback. Optional.
1403 * @param pvUser User argument for the progress callback.
1404 *
1405 * @thread Any thread. Will forward the request to EMT(0).
1406 * @vmstate Suspended, Running
1407 * @vmstateto Suspended.
1408 */
1409VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAftewards, PFNVMPROGRESS pfnProgress, void *pvUser)
1410{
1411 LogFlow(("VMR3Save: pVM=%p pszFilename=%p:{%s} fContinueAftewards=%RTbool pfnProgress=%p pvUser=%p\n",
1412 pVM, pszFilename, pszFilename, fContinueAftewards, pfnProgress, pvUser));
1413
1414 /*
1415 * Validate input.
1416 */
1417 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
1418 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
1419 AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
1420 AssertPtrNullReturn(pfnProgress, VERR_INVALID_POINTER);
1421
1422 /*
1423 * Request the operation in EMT(0).
1424 */
1425 SSMAFTER enmAfter = fContinueAftewards ? SSMAFTER_CONTINUE : SSMAFTER_DESTROY;
1426 PVMREQ pReq;
1427 int rc = VMR3ReqCall(pVM, 0 /* VCPU 0 */, &pReq, RT_INDEFINITE_WAIT,
1428 (PFNRT)vmR3Save, 5, pVM, pszFilename, enmAfter, pfnProgress, pvUser);
1429 if (RT_SUCCESS(rc))
1430 {
1431 rc = pReq->iStatus;
1432 VMR3ReqFree(pReq);
1433 }
1434
1435 LogFlow(("VMR3Save: returns %Rrc\n", rc));
1436 return rc;
1437}
1438
1439
1440/**
1441 * Worker for VMR3Save that validates the state and calls SSMR3Save.
1442 *
1443 * @returns 0 on success.
1444 * @returns VBox error code on failure.
1445 * @param pVM VM which state should be saved.
1446 * @param pszFilename Name of the save state file.
1447 * @param enmAfter What to do afterwards.
1448 * @param pfnProgress Progress callback. Optional.
1449 * @param pvUser User argument for the progress callback.
1450 * @thread EMT
1451 */
1452static DECLCALLBACK(int) vmR3Save(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser)
1453{
1454 LogFlow(("vmR3Save: pVM=%p pszFilename=%p:{%s} enmAfter=%d pfnProgress=%p pvUser=%p\n", pVM, pszFilename, pszFilename, enmAfter, pfnProgress, pvUser));
1455
1456 /*
1457 * Validate input.
1458 */
1459 /** @todo SMP: Check that vmR3SetState always done by EMT(0). If not add a vmR3TrySetState(). */
1460 AssertMsgReturn( pVM->enmVMState == VMSTATE_SUSPENDED
1461 || pVM->enmVMState == VMSTATE_RUNNING,
1462 ("%d\n", pVM->enmVMState),
1463 VERR_VM_INVALID_VM_STATE);
1464
1465 /* If we are in an inconsistent state, then we don't allow state saving. */
1466 if (pVM->vm.s.fPreventSaveState) /** @todo Incorporate VMINT::fPreventSaveState into the VMSTATE. There is a defect for this. */
1467 {
1468 LogRel(("VMM: vmR3Save: saving the VM state is not allowed at this moment\n"));
1469 return VERR_VM_SAVE_STATE_NOT_ALLOWED;
1470 }
1471
1472 /*
1473 * Change the state and perform the save.
1474 */
1475 bool fLive = pVM->enmVMState == VMSTATE_RUNNING;
1476 vmR3SetState(pVM, VMSTATE_SAVING); /** @todo Should probably use a different state for live snapshots and/or live migration. Will fix the state machine later. */
1477 int rc = SSMR3Save(pVM, pszFilename, enmAfter, pfnProgress, pvUser);
1478 vmR3SetState(pVM, VMSTATE_SUSPENDED);
1479
1480 return rc;
1481}
1482
1483
1484/**
1485 * Loads a new VM state.
1486 *
1487 * To restore a saved state on VM startup, call this function and then
1488 * resume the VM instead of powering it on.
1489 *
1490 * @returns 0 on success.
1491 * @returns VBox error code on failure.
1492 * @param pVM VM which state should be saved.
1493 * @param pszFilename Name of the save state file.
1494 * @param pfnProgress Progress callback. Optional.
1495 * @param pvUser User argument for the progress callback.
1496 * @thread Any thread.
1497 * @vmstate Created, Suspended
1498 * @vmstateto Suspended
1499 */
1500VMMR3DECL(int) VMR3Load(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser)
1501{
1502 LogFlow(("VMR3Load: pVM=%p pszFilename=%p:{%s} pfnProgress=%p pvUser=%p\n", pVM, pszFilename, pszFilename, pfnProgress, pvUser));
1503
1504 /*
1505 * Validate input.
1506 */
1507 if (!pVM)
1508 {
1509 AssertMsgFailed(("Invalid VM pointer\n"));
1510 return VERR_INVALID_PARAMETER;
1511 }
1512 if (!pszFilename)
1513 {
1514 AssertMsgFailed(("Must specify a filename to load the state from, wise guy!\n"));
1515 return VERR_INVALID_PARAMETER;
1516 }
1517
1518 /*
1519 * Request the operation in EMT.
1520 */
1521 PVMREQ pReq;
1522 int rc = VMR3ReqCall(pVM, 0 /* VCPU 0 */, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Load, 4, pVM, pszFilename, pfnProgress, pvUser);
1523 if (RT_SUCCESS(rc))
1524 {
1525 rc = pReq->iStatus;
1526 VMR3ReqFree(pReq);
1527 }
1528
1529 LogFlow(("VMR3Load: returns %Rrc\n", rc));
1530 return rc;
1531}
1532
1533
1534/**
1535 * Loads a new VM state.
1536 *
1537 * To restore a saved state on VM startup, call this function and then
1538 * resume the VM instead of powering it on.
1539 *
1540 * @returns 0 on success.
1541 * @returns VBox error code on failure.
1542 * @param pVM VM which state should be saved.
1543 * @param pszFilename Name of the save state file.
1544 * @param pfnProgress Progress callback. Optional.
1545 * @param pvUser User argument for the progress callback.
1546 * @thread EMT.
1547 */
1548static DECLCALLBACK(int) vmR3Load(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser)
1549{
1550 LogFlow(("vmR3Load: pVM=%p pszFilename=%p:{%s} pfnProgress=%p pvUser=%p\n", pVM, pszFilename, pszFilename, pfnProgress, pvUser));
1551
1552 /*
1553 * Validate input.
1554 */
1555 if ( pVM->enmVMState != VMSTATE_SUSPENDED
1556 && pVM->enmVMState != VMSTATE_CREATED)
1557 {
1558 AssertMsgFailed(("Invalid VM state %d\n", pVM->enmVMState));
1559 return VMSetError(pVM, VERR_VM_INVALID_VM_STATE, RT_SRC_POS, N_("Invalid VM state (%s) for restoring state from '%s'"),
1560 VMR3GetStateName(pVM->enmVMState), pszFilename);
1561 }
1562
1563 /*
1564 * Change the state and perform the load.
1565 */
1566 vmR3SetState(pVM, VMSTATE_LOADING);
1567 int rc = SSMR3Load(pVM, pszFilename, SSMAFTER_RESUME, pfnProgress, pvUser);
1568 if (RT_SUCCESS(rc))
1569 {
1570 /* Not paranoia anymore; the saved guest might use different hypervisor selectors. We must call VMR3Relocate. */
1571 VMR3Relocate(pVM, 0);
1572 vmR3SetState(pVM, VMSTATE_SUSPENDED);
1573 }
1574 else
1575 {
1576 vmR3SetState(pVM, VMSTATE_LOAD_FAILURE);
1577 rc = VMSetError(pVM, rc, RT_SRC_POS, N_("Unable to restore the virtual machine's saved state from '%s'. It may be damaged or from an older version of VirtualBox. Please discard the saved state before starting the virtual machine"), pszFilename);
1578 }
1579
1580 return rc;
1581}
1582
1583
1584/**
1585 * Power Off the VM.
1586 *
1587 * @returns 0 on success.
1588 * @returns VBox error code on failure.
1589 * @param pVM VM which should be destroyed.
1590 * @thread Any thread.
1591 * @vmstate Suspended, Running, Guru Meditation, Load Failure
1592 * @vmstateto Off
1593 */
1594VMMR3DECL(int) VMR3PowerOff(PVM pVM)
1595{
1596 LogFlow(("VMR3PowerOff: pVM=%p\n", pVM));
1597
1598 /*
1599 * Validate input.
1600 */
1601 if (!pVM)
1602 {
1603 AssertMsgFailed(("Invalid VM pointer\n"));
1604 return VERR_INVALID_PARAMETER;
1605 }
1606
1607 /*
1608 * Request the operation in EMT. (in reverse order as VCPU 0 does the actual work)
1609 */
1610 PVMREQ pReq = NULL;
1611 int rc = VMR3ReqCall(pVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3PowerOff, 1, pVM);
1612 if (RT_SUCCESS(rc))
1613 {
1614 rc = pReq->iStatus;
1615 VMR3ReqFree(pReq);
1616 }
1617 else
1618 Assert(pReq == NULL);
1619
1620 LogFlow(("VMR3PowerOff: returns %Rrc\n", rc));
1621 return rc;
1622}
1623
1624
1625/**
1626 * Power Off the VM.
1627 *
1628 * @returns 0 on success.
1629 * @returns VBox error code on failure.
1630 * @param pVM VM which should be destroyed.
1631 * @thread EMT.
1632 */
1633static DECLCALLBACK(int) vmR3PowerOff(PVM pVM)
1634{
1635 LogFlow(("vmR3PowerOff: pVM=%p\n", pVM));
1636
1637 /*
1638 * Validate input.
1639 */
1640 if ( pVM->enmVMState != VMSTATE_RUNNING
1641 && pVM->enmVMState != VMSTATE_SUSPENDED
1642 && pVM->enmVMState != VMSTATE_LOAD_FAILURE
1643 && pVM->enmVMState != VMSTATE_GURU_MEDITATION)
1644 {
1645 AssertMsgFailed(("Invalid VM state %d\n", pVM->enmVMState));
1646 return VERR_VM_INVALID_VM_STATE;
1647 }
1648
1649 /*
1650 * EMT(0) does the actual power off work here *after* all the other EMTs
1651 * have been thru and entered the STOPPED state.
1652 */
1653 PVMCPU pVCpu = VMMGetCpu(pVM);
1654 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STOPPED);
1655 if (pVCpu->idCpu != 0)
1656 return VINF_EM_OFF;
1657
1658 /*
1659 * For debugging purposes, we will log a summary of the guest state at this point.
1660 */
1661 if (pVM->enmVMState != VMSTATE_GURU_MEDITATION)
1662 {
1663 /* @todo SMP support? */
1664 PVMCPU pVCpu = VMMGetCpu(pVM);
1665
1666 /** @todo make the state dumping at VMR3PowerOff optional. */
1667 RTLogRelPrintf("****************** Guest state at power off ******************\n");
1668 DBGFR3Info(pVM, "cpumguest", "verbose", DBGFR3InfoLogRelHlp());
1669 RTLogRelPrintf("***\n");
1670 DBGFR3Info(pVM, "mode", NULL, DBGFR3InfoLogRelHlp());
1671 RTLogRelPrintf("***\n");
1672 DBGFR3Info(pVM, "activetimers", NULL, DBGFR3InfoLogRelHlp());
1673 RTLogRelPrintf("***\n");
1674 DBGFR3Info(pVM, "gdt", NULL, DBGFR3InfoLogRelHlp());
1675 /** @todo dump guest call stack. */
1676#if 1 // temporary while debugging #1589
1677 RTLogRelPrintf("***\n");
1678 uint32_t esp = CPUMGetGuestESP(pVCpu);
1679 if ( CPUMGetGuestSS(pVCpu) == 0
1680 && esp < _64K)
1681 {
1682 uint8_t abBuf[PAGE_SIZE];
1683 RTLogRelPrintf("***\n"
1684 "ss:sp=0000:%04x ", esp);
1685 uint32_t Start = esp & ~(uint32_t)63;
1686 int rc = PGMPhysSimpleReadGCPhys(pVM, abBuf, Start, 0x100);
1687 if (RT_SUCCESS(rc))
1688 RTLogRelPrintf("0000:%04x TO 0000:%04x:\n"
1689 "%.*Rhxd\n",
1690 Start, Start + 0x100 - 1,
1691 0x100, abBuf);
1692 else
1693 RTLogRelPrintf("rc=%Rrc\n", rc);
1694
1695 /* grub ... */
1696 if (esp < 0x2000 && esp > 0x1fc0)
1697 {
1698 rc = PGMPhysSimpleReadGCPhys(pVM, abBuf, 0x8000, 0x800);
1699 if (RT_SUCCESS(rc))
1700 RTLogRelPrintf("0000:8000 TO 0000:87ff:\n"
1701 "%.*Rhxd\n",
1702 0x800, abBuf);
1703 }
1704 /* microsoft cdrom hang ... */
1705 if (true)
1706 {
1707 rc = PGMPhysSimpleReadGCPhys(pVM, abBuf, 0x8000, 0x200);
1708 if (RT_SUCCESS(rc))
1709 RTLogRelPrintf("2000:0000 TO 2000:01ff:\n"
1710 "%.*Rhxd\n",
1711 0x200, abBuf);
1712 }
1713 }
1714#endif
1715 RTLogRelPrintf("************** End of Guest state at power off ***************\n");
1716 }
1717
1718 /*
1719 * Change the state to OFF and notify the components.
1720 */
1721 vmR3SetState(pVM, VMSTATE_OFF);
1722 PDMR3PowerOff(pVM);
1723
1724 return VINF_EM_OFF;
1725}
1726
1727
1728/**
1729 * Destroys the VM.
1730 * The VM must be powered off (or never really powered on) to call this function.
1731 * The VM handle is destroyed and can no longer be used up successful return.
1732 *
1733 * @returns VBox status code.
1734 * @param pVM VM which should be destroyed.
1735 * @thread Any thread but the emulation thread.
1736 * @vmstate Off, Created
1737 * @vmstateto N/A
1738 */
1739VMMR3DECL(int) VMR3Destroy(PVM pVM)
1740{
1741 LogFlow(("VMR3Destroy: pVM=%p\n", pVM));
1742
1743 /*
1744 * Validate input.
1745 */
1746 if (!pVM)
1747 return VERR_INVALID_PARAMETER;
1748 AssertPtrReturn(pVM, VERR_INVALID_POINTER);
1749 AssertMsgReturn( pVM->enmVMState == VMSTATE_OFF
1750 || pVM->enmVMState == VMSTATE_CREATED,
1751 ("Invalid VM state %d\n", pVM->enmVMState),
1752 VERR_VM_INVALID_VM_STATE);
1753
1754 /*
1755 * Change VM state to destroying and unlink the VM.
1756 */
1757 vmR3SetState(pVM, VMSTATE_DESTROYING);
1758
1759 /** @todo lock this when we start having multiple machines in a process... */
1760 PUVM pUVM = pVM->pUVM; AssertPtr(pUVM);
1761 if (g_pUVMsHead == pUVM)
1762 g_pUVMsHead = pUVM->pNext;
1763 else
1764 {
1765 PUVM pPrev = g_pUVMsHead;
1766 while (pPrev && pPrev->pNext != pUVM)
1767 pPrev = pPrev->pNext;
1768 AssertMsgReturn(pPrev, ("pUVM=%p / pVM=%p is INVALID!\n", pUVM, pVM), VERR_INVALID_PARAMETER);
1769
1770 pPrev->pNext = pUVM->pNext;
1771 }
1772 pUVM->pNext = NULL;
1773
1774 /*
1775 * Notify registered at destruction listeners.
1776 * (That's the debugger console.)
1777 */
1778 vmR3AtDtor(pVM);
1779
1780 /*
1781 * If we are the EMT of VCPU 0, then we'll delay the cleanup till later.
1782 */
1783 if (VMMGetCpuId(pVM) == 0)
1784 {
1785 pUVM->vm.s.fEMTDoesTheCleanup = true;
1786 pUVM->vm.s.fTerminateEMT = true;
1787 VM_FF_SET(pVM, VM_FF_TERMINATE);
1788
1789 /* Inform all other VCPUs too. */
1790 for (VMCPUID idCpu = 1; idCpu < pVM->cCPUs; idCpu++)
1791 {
1792 /*
1793 * Request EMT to do the larger part of the destruction.
1794 */
1795 PVMREQ pReq = NULL;
1796 int rc = VMR3ReqCallU(pUVM, idCpu, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)vmR3Destroy, 1, pVM);
1797 if (RT_SUCCESS(rc))
1798 rc = pReq->iStatus;
1799 AssertRC(rc);
1800 VMR3ReqFree(pReq);
1801 }
1802 }
1803 else
1804 {
1805 /*
1806 * Request EMT to do the larger part of the destruction. (in reverse order as VCPU 0 does the real cleanup)
1807 */
1808 PVMREQ pReq = NULL;
1809 int rc = VMR3ReqCallU(pUVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)vmR3Destroy, 1, pVM);
1810 if (RT_SUCCESS(rc))
1811 rc = pReq->iStatus;
1812 AssertRC(rc);
1813 VMR3ReqFree(pReq);
1814
1815 /*
1816 * Now do the final bit where the heap and VM structures are freed up.
1817 * This will also wait 30 secs for the emulation threads to terminate.
1818 */
1819 vmR3DestroyUVM(pUVM, 30000);
1820 }
1821
1822 LogFlow(("VMR3Destroy: returns VINF_SUCCESS\n"));
1823 return VINF_SUCCESS;
1824}
1825
1826
1827/**
1828 * Internal destruction worker.
1829 *
1830 * This will do nearly all of the job, including sacking the EMT.
1831 *
1832 * @returns VBox status.
1833 * @param pVM VM handle.
1834 */
1835DECLCALLBACK(int) vmR3Destroy(PVM pVM)
1836{
1837 PUVM pUVM = pVM->pUVM;
1838 PVMCPU pVCpu = VMMGetCpu(pVM);
1839
1840 NOREF(pUVM);
1841 LogFlow(("vmR3Destroy: pVM=%p pUVM=%p\n", pVM, pUVM));
1842 VM_ASSERT_EMT(pVM);
1843
1844 /* Only VCPU 0 does the full cleanup. */
1845 if (pVCpu->idCpu != 0)
1846 return VINF_EM_TERMINATE;
1847
1848 /*
1849 * Dump statistics to the log.
1850 */
1851#if defined(VBOX_WITH_STATISTICS) || defined(LOG_ENABLED)
1852 RTLogFlags(NULL, "nodisabled nobuffered");
1853#endif
1854#ifdef VBOX_WITH_STATISTICS
1855 STAMR3Dump(pVM, "*");
1856#else
1857 LogRel(("************************* Statistics *************************\n"));
1858 STAMR3DumpToReleaseLog(pVM, "*");
1859 LogRel(("********************* End of statistics **********************\n"));
1860#endif
1861
1862 /*
1863 * Destroy the VM components.
1864 */
1865 int rc = TMR3Term(pVM);
1866 AssertRC(rc);
1867#ifdef VBOX_WITH_DEBUGGER
1868 rc = DBGCTcpTerminate(pVM, pUVM->vm.s.pvDBGC);
1869 pVM->pUVM->vm.s.pvDBGC = NULL;
1870#endif
1871 AssertRC(rc);
1872 rc = DBGFR3Term(pVM);
1873 AssertRC(rc);
1874 rc = PDMR3Term(pVM);
1875 AssertRC(rc);
1876 rc = EMR3Term(pVM);
1877 AssertRC(rc);
1878 rc = IOMR3Term(pVM);
1879 AssertRC(rc);
1880 rc = CSAMR3Term(pVM);
1881 AssertRC(rc);
1882 rc = PATMR3Term(pVM);
1883 AssertRC(rc);
1884 rc = TRPMR3Term(pVM);
1885 AssertRC(rc);
1886 rc = SELMR3Term(pVM);
1887 AssertRC(rc);
1888 rc = REMR3Term(pVM);
1889 AssertRC(rc);
1890 rc = HWACCMR3Term(pVM);
1891 AssertRC(rc);
1892 rc = PGMR3Term(pVM);
1893 AssertRC(rc);
1894 rc = VMMR3Term(pVM); /* Terminates the ring-0 code! */
1895 AssertRC(rc);
1896 rc = CPUMR3Term(pVM);
1897 AssertRC(rc);
1898 rc = PDMR3CritSectTerm(pVM);
1899 AssertRC(rc);
1900 rc = MMR3Term(pVM);
1901 AssertRC(rc);
1902
1903 /*
1904 * We're done in this thread (EMT).
1905 */
1906 ASMAtomicUoWriteBool(&pVM->pUVM->vm.s.fTerminateEMT, true);
1907 ASMAtomicWriteU32(&pVM->fGlobalForcedActions, VM_FF_TERMINATE);
1908 LogFlow(("vmR3Destroy: returning %Rrc\n", VINF_EM_TERMINATE));
1909 return VINF_EM_TERMINATE;
1910}
1911
1912
1913/**
1914 * Destroys the shared VM structure, leaving only UVM behind.
1915 *
1916 * This is called by EMT right before terminating.
1917 *
1918 * @param pUVM The UVM handle.
1919 */
1920void vmR3DestroyFinalBitFromEMT(PUVM pUVM)
1921{
1922 if (pUVM->pVM)
1923 {
1924 PVMCPU pVCpu = VMMGetCpu(pUVM->pVM);
1925
1926 /* VCPU 0 does all the cleanup work. */
1927 if (pVCpu->idCpu != 0)
1928 return;
1929
1930 /*
1931 * Modify state and then terminate MM.
1932 * (MM must be delayed until this point so we don't destroy the callbacks and the request packet.)
1933 */
1934 vmR3SetState(pUVM->pVM, VMSTATE_TERMINATED);
1935
1936 /*
1937 * Tell GVMM to destroy the VM and free its resources.
1938 */
1939 int rc = SUPR3CallVMMR0Ex(pUVM->pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL);
1940 AssertRC(rc);
1941 pUVM->pVM = NULL;
1942 }
1943
1944 /*
1945 * Did an EMT call VMR3Destroy and end up having to do all the work?
1946 */
1947 if (pUVM->vm.s.fEMTDoesTheCleanup)
1948 vmR3DestroyUVM(pUVM, 30000);
1949}
1950
1951
1952/**
1953 * Destroys the UVM portion.
1954 *
1955 * This is called as the final step in the VM destruction or as the cleanup
1956 * in case of a creation failure. If EMT called VMR3Destroy, meaning
1957 * VMINTUSERPERVM::fEMTDoesTheCleanup is true, it will call this as
1958 * vmR3DestroyFinalBitFromEMT completes.
1959 *
1960 * @param pVM VM Handle.
1961 * @param cMilliesEMTWait The number of milliseconds to wait for the emulation
1962 * threads.
1963 */
1964static void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait)
1965{
1966 /*
1967 * Signal termination of each the emulation threads and
1968 * wait for them to complete.
1969 */
1970 /* Signal them. */
1971 ASMAtomicUoWriteBool(&pUVM->vm.s.fTerminateEMT, true);
1972 for (VMCPUID i = 0; i < pUVM->cCpus; i++)
1973 {
1974 ASMAtomicUoWriteBool(&pUVM->aCpus[i].vm.s.fTerminateEMT, true);
1975 if (pUVM->pVM)
1976 VM_FF_SET(pUVM->pVM, VM_FF_TERMINATE);
1977 VMR3NotifyGlobalFFU(pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
1978 RTSemEventSignal(pUVM->aCpus[i].vm.s.EventSemWait);
1979 }
1980
1981 /* Wait for them. */
1982 uint64_t NanoTS = RTTimeNanoTS();
1983 RTTHREAD hSelf = RTThreadSelf();
1984 ASMAtomicUoWriteBool(&pUVM->vm.s.fTerminateEMT, true);
1985 for (VMCPUID i = 0; i < pUVM->cCpus; i++)
1986 {
1987 RTTHREAD hThread = pUVM->aCpus[i].vm.s.ThreadEMT;
1988 if ( hThread != NIL_RTTHREAD
1989 && hThread != hSelf)
1990 {
1991 uint64_t cMilliesElapsed = (RTTimeNanoTS() - NanoTS) / 1000000;
1992 int rc2 = RTThreadWait(hThread,
1993 cMilliesElapsed < cMilliesEMTWait
1994 ? RT_MAX(cMilliesEMTWait - cMilliesElapsed, 2000)
1995 : 2000,
1996 NULL);
1997 if (rc2 == VERR_TIMEOUT) /* avoid the assertion when debugging. */
1998 rc2 = RTThreadWait(hThread, 1000, NULL);
1999 AssertLogRelMsgRC(rc2, ("i=%u rc=%Rrc\n", i, rc2));
2000 if (RT_SUCCESS(rc2))
2001 pUVM->aCpus[0].vm.s.ThreadEMT = NIL_RTTHREAD;
2002 }
2003 }
2004
2005 /* Cleanup the semaphores. */
2006 for (VMCPUID i = 0; i < pUVM->cCpus; i++)
2007 {
2008 RTSemEventDestroy(pUVM->aCpus[i].vm.s.EventSemWait);
2009 pUVM->aCpus[i].vm.s.EventSemWait = NIL_RTSEMEVENT;
2010 }
2011
2012 /*
2013 * Free the event semaphores associated with the request packets.
2014 */
2015 unsigned cReqs = 0;
2016 for (unsigned i = 0; i < RT_ELEMENTS(pUVM->vm.s.apReqFree); i++)
2017 {
2018 PVMREQ pReq = pUVM->vm.s.apReqFree[i];
2019 pUVM->vm.s.apReqFree[i] = NULL;
2020 for (; pReq; pReq = pReq->pNext, cReqs++)
2021 {
2022 pReq->enmState = VMREQSTATE_INVALID;
2023 RTSemEventDestroy(pReq->EventSem);
2024 }
2025 }
2026 Assert(cReqs == pUVM->vm.s.cReqFree); NOREF(cReqs);
2027
2028 /*
2029 * Kill all queued requests. (There really shouldn't be any!)
2030 */
2031 for (unsigned i = 0; i < 10; i++)
2032 {
2033 PVMREQ pReqHead = (PVMREQ)ASMAtomicXchgPtr((void *volatile *)&pUVM->vm.s.pReqs, NULL);
2034 AssertMsg(!pReqHead, ("This isn't supposed to happen! VMR3Destroy caller has to serialize this.\n"));
2035 if (!pReqHead)
2036 break;
2037 for (PVMREQ pReq = pReqHead; pReq; pReq = pReq->pNext)
2038 {
2039 ASMAtomicUoWriteSize(&pReq->iStatus, VERR_INTERNAL_ERROR);
2040 ASMAtomicWriteSize(&pReq->enmState, VMREQSTATE_INVALID);
2041 RTSemEventSignal(pReq->EventSem);
2042 RTThreadSleep(2);
2043 RTSemEventDestroy(pReq->EventSem);
2044 }
2045 /* give them a chance to respond before we free the request memory. */
2046 RTThreadSleep(32);
2047 }
2048
2049 /*
2050 * Now all queued VCPU requests (again, there shouldn't be any).
2051 */
2052 for (VMCPUID i = 0; i < pUVM->cCpus; i++)
2053 {
2054 PUVMCPU pUVCpu = &pUVM->aCpus[i];
2055
2056 for (unsigned i = 0; i < 10; i++)
2057 {
2058 PVMREQ pReqHead = (PVMREQ)ASMAtomicXchgPtr((void *volatile *)&pUVCpu->vm.s.pReqs, NULL);
2059 AssertMsg(!pReqHead, ("This isn't supposed to happen! VMR3Destroy caller has to serialize this.\n"));
2060 if (!pReqHead)
2061 break;
2062 for (PVMREQ pReq = pReqHead; pReq; pReq = pReq->pNext)
2063 {
2064 ASMAtomicUoWriteSize(&pReq->iStatus, VERR_INTERNAL_ERROR);
2065 ASMAtomicWriteSize(&pReq->enmState, VMREQSTATE_INVALID);
2066 RTSemEventSignal(pReq->EventSem);
2067 RTThreadSleep(2);
2068 RTSemEventDestroy(pReq->EventSem);
2069 }
2070 /* give them a chance to respond before we free the request memory. */
2071 RTThreadSleep(32);
2072 }
2073 }
2074
2075 /*
2076 * Make sure the VMMR0.r0 module and whatever else is unloaded.
2077 */
2078 PDMR3TermUVM(pUVM);
2079
2080 /*
2081 * Terminate the support library if initialized.
2082 */
2083 if (pUVM->vm.s.pSession)
2084 {
2085 int rc = SUPR3Term(false /*fForced*/);
2086 AssertRC(rc);
2087 pUVM->vm.s.pSession = NIL_RTR0PTR;
2088 }
2089
2090 /*
2091 * Destroy the MM heap and free the UVM structure.
2092 */
2093 MMR3TermUVM(pUVM);
2094 STAMR3TermUVM(pUVM);
2095
2096#ifdef LOG_ENABLED
2097 RTLogSetCustomPrefixCallback(NULL, NULL, NULL);
2098#endif
2099 RTTlsFree(pUVM->vm.s.idxTLS);
2100
2101 ASMAtomicUoWriteU32(&pUVM->u32Magic, UINT32_MAX);
2102 RTMemFree(pUVM);
2103
2104 RTLogFlush(NULL);
2105}
2106
2107
2108/**
2109 * Enumerates the VMs in this process.
2110 *
2111 * @returns Pointer to the next VM.
2112 * @returns NULL when no more VMs.
2113 * @param pVMPrev The previous VM
2114 * Use NULL to start the enumeration.
2115 */
2116VMMR3DECL(PVM) VMR3EnumVMs(PVM pVMPrev)
2117{
2118 /*
2119 * This is quick and dirty. It has issues with VM being
2120 * destroyed during the enumeration.
2121 */
2122 PUVM pNext;
2123 if (pVMPrev)
2124 pNext = pVMPrev->pUVM->pNext;
2125 else
2126 pNext = g_pUVMsHead;
2127 return pNext ? pNext->pVM : NULL;
2128}
2129
2130
2131/**
2132 * Registers an at VM destruction callback.
2133 *
2134 * @returns VBox status code.
2135 * @param pfnAtDtor Pointer to callback.
2136 * @param pvUser User argument.
2137 */
2138VMMR3DECL(int) VMR3AtDtorRegister(PFNVMATDTOR pfnAtDtor, void *pvUser)
2139{
2140 /*
2141 * Check if already registered.
2142 */
2143 VM_ATDTOR_LOCK();
2144 PVMATDTOR pCur = g_pVMAtDtorHead;
2145 while (pCur)
2146 {
2147 if (pfnAtDtor == pCur->pfnAtDtor)
2148 {
2149 VM_ATDTOR_UNLOCK();
2150 AssertMsgFailed(("Already registered at destruction callback %p!\n", pfnAtDtor));
2151 return VERR_INVALID_PARAMETER;
2152 }
2153
2154 /* next */
2155 pCur = pCur->pNext;
2156 }
2157 VM_ATDTOR_UNLOCK();
2158
2159 /*
2160 * Allocate new entry.
2161 */
2162 PVMATDTOR pVMAtDtor = (PVMATDTOR)RTMemAlloc(sizeof(*pVMAtDtor));
2163 if (!pVMAtDtor)
2164 return VERR_NO_MEMORY;
2165
2166 VM_ATDTOR_LOCK();
2167 pVMAtDtor->pfnAtDtor = pfnAtDtor;
2168 pVMAtDtor->pvUser = pvUser;
2169 pVMAtDtor->pNext = g_pVMAtDtorHead;
2170 g_pVMAtDtorHead = pVMAtDtor;
2171 VM_ATDTOR_UNLOCK();
2172
2173 return VINF_SUCCESS;
2174}
2175
2176
2177/**
2178 * Deregisters an at VM destruction callback.
2179 *
2180 * @returns VBox status code.
2181 * @param pfnAtDtor Pointer to callback.
2182 */
2183VMMR3DECL(int) VMR3AtDtorDeregister(PFNVMATDTOR pfnAtDtor)
2184{
2185 /*
2186 * Find it, unlink it and free it.
2187 */
2188 VM_ATDTOR_LOCK();
2189 PVMATDTOR pPrev = NULL;
2190 PVMATDTOR pCur = g_pVMAtDtorHead;
2191 while (pCur)
2192 {
2193 if (pfnAtDtor == pCur->pfnAtDtor)
2194 {
2195 if (pPrev)
2196 pPrev->pNext = pCur->pNext;
2197 else
2198 g_pVMAtDtorHead = pCur->pNext;
2199 pCur->pNext = NULL;
2200 VM_ATDTOR_UNLOCK();
2201
2202 RTMemFree(pCur);
2203 return VINF_SUCCESS;
2204 }
2205
2206 /* next */
2207 pPrev = pCur;
2208 pCur = pCur->pNext;
2209 }
2210 VM_ATDTOR_UNLOCK();
2211
2212 return VERR_INVALID_PARAMETER;
2213}
2214
2215
2216/**
2217 * Walks the list of at VM destructor callbacks.
2218 * @param pVM The VM which is about to be destroyed.
2219 */
2220static void vmR3AtDtor(PVM pVM)
2221{
2222 /*
2223 * Find it, unlink it and free it.
2224 */
2225 VM_ATDTOR_LOCK();
2226 for (PVMATDTOR pCur = g_pVMAtDtorHead; pCur; pCur = pCur->pNext)
2227 pCur->pfnAtDtor(pVM, pCur->pvUser);
2228 VM_ATDTOR_UNLOCK();
2229}
2230
2231
2232/**
2233 * Reset the current VM.
2234 *
2235 * @returns VBox status code.
2236 * @param pVM VM to reset.
2237 */
2238VMMR3DECL(int) VMR3Reset(PVM pVM)
2239{
2240 int rc = VINF_SUCCESS;
2241
2242 /*
2243 * Check the state.
2244 */
2245 if (!pVM)
2246 return VERR_INVALID_PARAMETER;
2247 if ( pVM->enmVMState != VMSTATE_RUNNING
2248 && pVM->enmVMState != VMSTATE_SUSPENDED)
2249 {
2250 AssertMsgFailed(("Invalid VM state %d\n", pVM->enmVMState));
2251 return VERR_VM_INVALID_VM_STATE;
2252 }
2253
2254 /*
2255 * Queue reset request to the emulation thread
2256 * and wait for it to be processed. (in reverse order as VCPU 0 does the real cleanup)
2257 */
2258 PVMREQ pReq = NULL;
2259 rc = VMR3ReqCall(pVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Reset, 1, pVM);
2260 if (RT_SUCCESS(rc))
2261 rc = pReq->iStatus;
2262 AssertRC(rc);
2263 VMR3ReqFree(pReq);
2264
2265 return rc;
2266}
2267
2268
2269/**
2270 * Worker which checks integrity of some internal structures.
2271 * This is yet another attempt to track down that AVL tree crash.
2272 */
2273static void vmR3CheckIntegrity(PVM pVM)
2274{
2275#ifdef VBOX_STRICT
2276 int rc = PGMR3CheckIntegrity(pVM);
2277 AssertReleaseRC(rc);
2278#endif
2279}
2280
2281
2282/**
2283 * Reset request processor.
2284 *
2285 * This is called by the emulation threads as a response to the
2286 * reset request issued by VMR3Reset().
2287 *
2288 * @returns VBox status code.
2289 * @param pVM VM to reset.
2290 */
2291static DECLCALLBACK(int) vmR3Reset(PVM pVM)
2292{
2293 PVMCPU pVCpu = VMMGetCpu(pVM);
2294
2295 /*
2296 * EMT(0) does the full cleanup *after* all the other EMTs has been
2297 * thru here and been told to enter the EMSTATE_WAIT_SIPI state.
2298 */
2299 VMCPU_ASSERT_STATE(pVCpu, VMCPUSTATE_STARTED);
2300
2301 /* Clear all pending forced actions. */
2302 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_ALL_MASK & ~VMCPU_FF_REQUEST);
2303
2304 if (pVCpu->idCpu != 0)
2305 {
2306 CPUMR3ResetCpu(pVCpu);
2307 return VINF_EM_RESET;
2308 }
2309
2310 /*
2311 * As a safety precaution we temporarily change the state while resetting.
2312 * (If VMR3Reset was not called from EMT we might have change state... let's ignore that fact for now.)
2313 */
2314 VMSTATE enmVMState = pVM->enmVMState;
2315 Assert(enmVMState == VMSTATE_SUSPENDED || enmVMState == VMSTATE_RUNNING);
2316 vmR3SetState(pVM, VMSTATE_RESETTING);
2317 vmR3CheckIntegrity(pVM);
2318
2319
2320 /*
2321 * Reset the VM components.
2322 */
2323 PATMR3Reset(pVM);
2324 CSAMR3Reset(pVM);
2325 PGMR3Reset(pVM); /* We clear VM RAM in PGMR3Reset. It's vital PDMR3Reset is executed
2326 * _afterwards_. E.g. ACPI sets up RAM tables during init/reset. */
2327 MMR3Reset(pVM);
2328 PDMR3Reset(pVM);
2329 SELMR3Reset(pVM);
2330 TRPMR3Reset(pVM);
2331 vmR3AtResetU(pVM->pUVM);
2332 REMR3Reset(pVM);
2333 IOMR3Reset(pVM);
2334 CPUMR3Reset(pVM);
2335 TMR3Reset(pVM);
2336 EMR3Reset(pVM);
2337 HWACCMR3Reset(pVM); /* This must come *after* PATM, CSAM, CPUM, SELM and TRPM. */
2338
2339#ifdef LOG_ENABLED
2340 /*
2341 * Debug logging.
2342 */
2343 RTLogPrintf("\n\nThe VM was reset:\n");
2344 DBGFR3Info(pVM, "cpum", "verbose", NULL);
2345#endif
2346
2347 /*
2348 * Restore the state.
2349 */
2350 vmR3CheckIntegrity(pVM);
2351 Assert(pVM->enmVMState == VMSTATE_RESETTING);
2352 vmR3SetState(pVM, enmVMState);
2353
2354 return VINF_EM_RESET;
2355}
2356
2357
2358/**
2359 * Walks the list of at VM reset callbacks and calls them
2360 *
2361 * @returns VBox status code.
2362 * Any failure is fatal.
2363 * @param pUVM Pointe to the user mode VM structure.
2364 */
2365static int vmR3AtResetU(PUVM pUVM)
2366{
2367 /*
2368 * Walk the list and call them all.
2369 */
2370 int rc = VINF_SUCCESS;
2371 for (PVMATRESET pCur = pUVM->vm.s.pAtReset; pCur; pCur = pCur->pNext)
2372 {
2373 /* do the call */
2374 switch (pCur->enmType)
2375 {
2376 case VMATRESETTYPE_DEV:
2377 rc = pCur->u.Dev.pfnCallback(pCur->u.Dev.pDevIns, pCur->pvUser);
2378 break;
2379 case VMATRESETTYPE_INTERNAL:
2380 rc = pCur->u.Internal.pfnCallback(pUVM->pVM, pCur->pvUser);
2381 break;
2382 case VMATRESETTYPE_EXTERNAL:
2383 pCur->u.External.pfnCallback(pCur->pvUser);
2384 break;
2385 default:
2386 AssertMsgFailed(("Invalid at-reset type %d!\n", pCur->enmType));
2387 return VERR_INTERNAL_ERROR;
2388 }
2389
2390 if (RT_FAILURE(rc))
2391 {
2392 AssertMsgFailed(("At-reset handler %s failed with rc=%d\n", pCur->pszDesc, rc));
2393 return rc;
2394 }
2395 }
2396
2397 return VINF_SUCCESS;
2398}
2399
2400
2401/**
2402 * Internal registration function
2403 */
2404static int vmr3AtResetRegisterU(PUVM pUVM, void *pvUser, const char *pszDesc, PVMATRESET *ppNew)
2405{
2406 /*
2407 * Allocate restration structure.
2408 */
2409 PVMATRESET pNew = (PVMATRESET)MMR3HeapAllocU(pUVM, MM_TAG_VM, sizeof(*pNew));
2410 if (pNew)
2411 {
2412 /* fill data. */
2413 pNew->pszDesc = pszDesc;
2414 pNew->pvUser = pvUser;
2415
2416 /* insert */
2417 pNew->pNext = *pUVM->vm.s.ppAtResetNext;
2418 *pUVM->vm.s.ppAtResetNext = pNew;
2419 pUVM->vm.s.ppAtResetNext = &pNew->pNext;
2420
2421 *ppNew = pNew;
2422 return VINF_SUCCESS;
2423 }
2424 return VERR_NO_MEMORY;
2425}
2426
2427
2428/**
2429 * Registers an at VM reset callback.
2430 *
2431 * @returns VBox status code.
2432 * @param pVM The VM.
2433 * @param pDevInst Device instance.
2434 * @param pfnCallback Callback function.
2435 * @param pvUser User argument.
2436 * @param pszDesc Description (optional).
2437 */
2438VMMR3DECL(int) VMR3AtResetRegister(PVM pVM, PPDMDEVINS pDevInst, PFNVMATRESET pfnCallback, void *pvUser, const char *pszDesc)
2439{
2440 /*
2441 * Validate.
2442 */
2443 if (!pDevInst)
2444 {
2445 AssertMsgFailed(("pDevIns is NULL!\n"));
2446 return VERR_INVALID_PARAMETER;
2447 }
2448
2449 /*
2450 * Create the new entry.
2451 */
2452 PVMATRESET pNew;
2453 int rc = vmr3AtResetRegisterU(pVM->pUVM, pvUser, pszDesc, &pNew);
2454 if (RT_SUCCESS(rc))
2455 {
2456 /*
2457 * Fill in type data.
2458 */
2459 pNew->enmType = VMATRESETTYPE_DEV;
2460 pNew->u.Dev.pfnCallback = pfnCallback;
2461 pNew->u.Dev.pDevIns = pDevInst;
2462 }
2463
2464 return rc;
2465}
2466
2467
2468/**
2469 * Registers an at VM reset internal callback.
2470 *
2471 * @returns VBox status code.
2472 * @param pVM The VM.
2473 * @param pfnCallback Callback function.
2474 * @param pvUser User argument.
2475 * @param pszDesc Description (optional).
2476 */
2477VMMR3DECL(int) VMR3AtResetRegisterInternal(PVM pVM, PFNVMATRESETINT pfnCallback, void *pvUser, const char *pszDesc)
2478{
2479 /*
2480 * Validate.
2481 */
2482 if (!pfnCallback)
2483 {
2484 AssertMsgFailed(("pfnCallback is NULL!\n"));
2485 return VERR_INVALID_PARAMETER;
2486 }
2487
2488 /*
2489 * Create the new entry.
2490 */
2491 PVMATRESET pNew;
2492 int rc = vmr3AtResetRegisterU(pVM->pUVM, pvUser, pszDesc, &pNew);
2493 if (RT_SUCCESS(rc))
2494 {
2495 /*
2496 * Fill in type data.
2497 */
2498 pNew->enmType = VMATRESETTYPE_INTERNAL;
2499 pNew->u.Internal.pfnCallback = pfnCallback;
2500 }
2501
2502 return rc;
2503}
2504
2505
2506/**
2507 * Registers an at VM reset external callback.
2508 *
2509 * @returns VBox status code.
2510 * @param pVM The VM.
2511 * @param pfnCallback Callback function.
2512 * @param pvUser User argument.
2513 * @param pszDesc Description (optional).
2514 */
2515VMMR3DECL(int) VMR3AtResetRegisterExternal(PVM pVM, PFNVMATRESETEXT pfnCallback, void *pvUser, const char *pszDesc)
2516{
2517 /*
2518 * Validate.
2519 */
2520 if (!pfnCallback)
2521 {
2522 AssertMsgFailed(("pfnCallback is NULL!\n"));
2523 return VERR_INVALID_PARAMETER;
2524 }
2525
2526 /*
2527 * Create the new entry.
2528 */
2529 PVMATRESET pNew;
2530 int rc = vmr3AtResetRegisterU(pVM->pUVM, pvUser, pszDesc, &pNew);
2531 if (RT_SUCCESS(rc))
2532 {
2533 /*
2534 * Fill in type data.
2535 */
2536 pNew->enmType = VMATRESETTYPE_EXTERNAL;
2537 pNew->u.External.pfnCallback = pfnCallback;
2538 }
2539
2540 return rc;
2541}
2542
2543
2544/**
2545 * Unlinks and frees a callback.
2546 *
2547 * @returns Pointer to the next callback structure.
2548 * @param pUVM Pointer to the user mode VM structure.
2549 * @param pCur The one to free.
2550 * @param pPrev The one before pCur.
2551 */
2552static PVMATRESET vmr3AtResetFreeU(PUVM pUVM, PVMATRESET pCur, PVMATRESET pPrev)
2553{
2554 /*
2555 * Unlink it.
2556 */
2557 PVMATRESET pNext = pCur->pNext;
2558 if (pPrev)
2559 {
2560 pPrev->pNext = pNext;
2561 if (!pNext)
2562 pUVM->vm.s.ppAtResetNext = &pPrev->pNext;
2563 }
2564 else
2565 {
2566 pUVM->vm.s.pAtReset = pNext;
2567 if (!pNext)
2568 pUVM->vm.s.ppAtResetNext = &pUVM->vm.s.pAtReset;
2569 }
2570
2571 /*
2572 * Free it.
2573 */
2574 MMR3HeapFree(pCur);
2575
2576 return pNext;
2577}
2578
2579
2580/**
2581 * Deregisters an at VM reset callback.
2582 *
2583 * @returns VBox status code.
2584 * @param pVM The VM.
2585 * @param pDevIns Device instance.
2586 * @param pfnCallback Callback function.
2587 */
2588VMMR3DECL(int) VMR3AtResetDeregister(PVM pVM, PPDMDEVINS pDevIns, PFNVMATRESET pfnCallback)
2589{
2590 int rc = VERR_VM_ATRESET_NOT_FOUND;
2591 PVMATRESET pPrev = NULL;
2592 PVMATRESET pCur = pVM->pUVM->vm.s.pAtReset;
2593 while (pCur)
2594 {
2595 if ( pCur->enmType == VMATRESETTYPE_DEV
2596 && pCur->u.Dev.pDevIns == pDevIns
2597 && ( !pfnCallback
2598 || pCur->u.Dev.pfnCallback == pfnCallback))
2599 {
2600 pCur = vmr3AtResetFreeU(pVM->pUVM, pCur, pPrev);
2601 rc = VINF_SUCCESS;
2602 }
2603 else
2604 {
2605 pPrev = pCur;
2606 pCur = pCur->pNext;
2607 }
2608 }
2609
2610 AssertRC(rc);
2611 return rc;
2612}
2613
2614
2615/**
2616 * Deregisters an at VM reset internal callback.
2617 *
2618 * @returns VBox status code.
2619 * @param pVM The VM.
2620 * @param pfnCallback Callback function.
2621 */
2622VMMR3DECL(int) VMR3AtResetDeregisterInternal(PVM pVM, PFNVMATRESETINT pfnCallback)
2623{
2624 int rc = VERR_VM_ATRESET_NOT_FOUND;
2625 PVMATRESET pPrev = NULL;
2626 PVMATRESET pCur = pVM->pUVM->vm.s.pAtReset;
2627 while (pCur)
2628 {
2629 if ( pCur->enmType == VMATRESETTYPE_INTERNAL
2630 && pCur->u.Internal.pfnCallback == pfnCallback)
2631 {
2632 pCur = vmr3AtResetFreeU(pVM->pUVM, pCur, pPrev);
2633 rc = VINF_SUCCESS;
2634 }
2635 else
2636 {
2637 pPrev = pCur;
2638 pCur = pCur->pNext;
2639 }
2640 }
2641
2642 AssertRC(rc);
2643 return rc;
2644}
2645
2646
2647/**
2648 * Deregisters an at VM reset external callback.
2649 *
2650 * @returns VBox status code.
2651 * @param pVM The VM.
2652 * @param pfnCallback Callback function.
2653 */
2654VMMR3DECL(int) VMR3AtResetDeregisterExternal(PVM pVM, PFNVMATRESETEXT pfnCallback)
2655{
2656 int rc = VERR_VM_ATRESET_NOT_FOUND;
2657 PVMATRESET pPrev = NULL;
2658 PVMATRESET pCur = pVM->pUVM->vm.s.pAtReset;
2659 while (pCur)
2660 {
2661 if ( pCur->enmType == VMATRESETTYPE_INTERNAL
2662 && pCur->u.External.pfnCallback == pfnCallback)
2663 {
2664 pCur = vmr3AtResetFreeU(pVM->pUVM, pCur, pPrev);
2665 rc = VINF_SUCCESS;
2666 }
2667 else
2668 {
2669 pPrev = pCur;
2670 pCur = pCur->pNext;
2671 }
2672 }
2673
2674 AssertRC(rc);
2675 return rc;
2676}
2677
2678
2679/**
2680 * Gets the current VM state.
2681 *
2682 * @returns The current VM state.
2683 * @param pVM VM handle.
2684 * @thread Any
2685 */
2686VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM)
2687{
2688 return pVM->enmVMState;
2689}
2690
2691
2692/**
2693 * Gets the state name string for a VM state.
2694 *
2695 * @returns Pointer to the state name. (readonly)
2696 * @param enmState The state.
2697 */
2698VMMR3DECL(const char *) VMR3GetStateName(VMSTATE enmState)
2699{
2700 switch (enmState)
2701 {
2702 case VMSTATE_CREATING: return "CREATING";
2703 case VMSTATE_CREATED: return "CREATED";
2704 case VMSTATE_RUNNING: return "RUNNING";
2705 case VMSTATE_LOADING: return "LOADING";
2706 case VMSTATE_LOAD_FAILURE: return "LOAD_FAILURE";
2707 case VMSTATE_SAVING: return "SAVING";
2708 case VMSTATE_SUSPENDED: return "SUSPENDED";
2709 case VMSTATE_RESETTING: return "RESETTING";
2710 case VMSTATE_GURU_MEDITATION: return "GURU_MEDITATION";
2711 case VMSTATE_OFF: return "OFF";
2712 case VMSTATE_DESTROYING: return "DESTROYING";
2713 case VMSTATE_TERMINATED: return "TERMINATED";
2714 default:
2715 AssertMsgFailed(("Unknown state %d\n", enmState));
2716 return "Unknown!\n";
2717 }
2718}
2719
2720
2721/**
2722 * Sets the current VM state.
2723 *
2724 * @returns The current VM state.
2725 * @param pVM VM handle.
2726 * @param enmStateNew The new state.
2727 */
2728void vmR3SetState(PVM pVM, VMSTATE enmStateNew)
2729{
2730 /*
2731 * Validate state machine transitions before doing the actual change.
2732 */
2733 VMSTATE enmStateOld = pVM->enmVMState;
2734 switch (enmStateOld)
2735 {
2736 case VMSTATE_OFF:
2737 Assert(enmStateNew != VMSTATE_GURU_MEDITATION);
2738 break;
2739
2740 default:
2741 /** @todo full validation. */
2742 break;
2743 }
2744
2745 pVM->enmVMState = enmStateNew;
2746 LogRel(("Changing the VM state from '%s' to '%s'.\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)));
2747
2748 /*
2749 * Call the at state change callbacks.
2750 */
2751 for (PVMATSTATE pCur = pVM->pUVM->vm.s.pAtState; pCur; pCur = pCur->pNext)
2752 {
2753 pCur->pfnAtState(pVM, enmStateNew, enmStateOld, pCur->pvUser);
2754 if ( pVM->enmVMState != enmStateNew
2755 && pVM->enmVMState == VMSTATE_DESTROYING)
2756 break;
2757 AssertMsg(pVM->enmVMState == enmStateNew,
2758 ("You are not allowed to change the state while in the change callback, except "
2759 "from destroying the VM. There are restrictions in the way the state changes "
2760 "are propagated up to the EM execution loop and it makes the program flow very "
2761 "difficult to follow.\n"));
2762 }
2763}
2764
2765
2766/**
2767 * Registers a VM state change callback.
2768 *
2769 * You are not allowed to call any function which changes the VM state from a
2770 * state callback, except VMR3Destroy().
2771 *
2772 * @returns VBox status code.
2773 * @param pVM VM handle.
2774 * @param pfnAtState Pointer to callback.
2775 * @param pvUser User argument.
2776 * @thread Any.
2777 */
2778VMMR3DECL(int) VMR3AtStateRegister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser)
2779{
2780 LogFlow(("VMR3AtStateRegister: pfnAtState=%p pvUser=%p\n", pfnAtState, pvUser));
2781
2782 /*
2783 * Validate input.
2784 */
2785 if (!pfnAtState)
2786 {
2787 AssertMsgFailed(("callback is required\n"));
2788 return VERR_INVALID_PARAMETER;
2789 }
2790
2791 /*
2792 * Make sure we're in EMT (to avoid the logging).
2793 */
2794 PVMREQ pReq;
2795 int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3AtStateRegisterU, 3, pVM->pUVM, pfnAtState, pvUser);
2796 if (RT_FAILURE(rc))
2797 return rc;
2798 rc = pReq->iStatus;
2799 VMR3ReqFree(pReq);
2800
2801 LogFlow(("VMR3AtStateRegister: returns %Rrc\n", rc));
2802 return rc;
2803}
2804
2805
2806/**
2807 * Registers a VM state change callback.
2808 *
2809 * @returns VBox status code.
2810 * @param pUVM Pointer to the user mode VM structure.
2811 * @param pfnAtState Pointer to callback.
2812 * @param pvUser User argument.
2813 * @thread EMT
2814 */
2815static DECLCALLBACK(int) vmR3AtStateRegisterU(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser)
2816{
2817 /*
2818 * Allocate a new record.
2819 */
2820
2821 PVMATSTATE pNew = (PVMATSTATE)MMR3HeapAllocU(pUVM, MM_TAG_VM, sizeof(*pNew));
2822 if (!pNew)
2823 return VERR_NO_MEMORY;
2824
2825 /* fill */
2826 pNew->pfnAtState = pfnAtState;
2827 pNew->pvUser = pvUser;
2828
2829 /* insert */
2830 pNew->pNext = *pUVM->vm.s.ppAtStateNext;
2831 *pUVM->vm.s.ppAtStateNext = pNew;
2832 pUVM->vm.s.ppAtStateNext = &pNew->pNext;
2833
2834 return VINF_SUCCESS;
2835}
2836
2837
2838/**
2839 * Deregisters a VM state change callback.
2840 *
2841 * @returns VBox status code.
2842 * @param pVM VM handle.
2843 * @param pfnAtState Pointer to callback.
2844 * @param pvUser User argument.
2845 * @thread Any.
2846 */
2847VMMR3DECL(int) VMR3AtStateDeregister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser)
2848{
2849 LogFlow(("VMR3AtStateDeregister: pfnAtState=%p pvUser=%p\n", pfnAtState, pvUser));
2850
2851 /*
2852 * Validate input.
2853 */
2854 if (!pfnAtState)
2855 {
2856 AssertMsgFailed(("callback is required\n"));
2857 return VERR_INVALID_PARAMETER;
2858 }
2859
2860 /*
2861 * Make sure we're in EMT (to avoid the logging).
2862 */
2863 PVMREQ pReq;
2864 int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3AtStateDeregisterU, 3, pVM->pUVM, pfnAtState, pvUser);
2865 if (RT_FAILURE(rc))
2866 return rc;
2867 rc = pReq->iStatus;
2868 VMR3ReqFree(pReq);
2869
2870 LogFlow(("VMR3AtStateDeregister: returns %Rrc\n", rc));
2871 return rc;
2872}
2873
2874
2875/**
2876 * Deregisters a VM state change callback.
2877 *
2878 * @returns VBox status code.
2879 * @param pUVM Pointer to the user mode VM structure.
2880 * @param pfnAtState Pointer to callback.
2881 * @param pvUser User argument.
2882 * @thread EMT
2883 */
2884static DECLCALLBACK(int) vmR3AtStateDeregisterU(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser)
2885{
2886 LogFlow(("vmR3AtStateDeregisterU: pfnAtState=%p pvUser=%p\n", pfnAtState, pvUser));
2887
2888 /*
2889 * Search the list for the entry.
2890 */
2891 PVMATSTATE pPrev = NULL;
2892 PVMATSTATE pCur = pUVM->vm.s.pAtState;
2893 while ( pCur
2894 && ( pCur->pfnAtState != pfnAtState
2895 || pCur->pvUser != pvUser))
2896 {
2897 pPrev = pCur;
2898 pCur = pCur->pNext;
2899 }
2900 if (!pCur)
2901 {
2902 AssertMsgFailed(("pfnAtState=%p was not found\n", pfnAtState));
2903 return VERR_FILE_NOT_FOUND;
2904 }
2905
2906 /*
2907 * Unlink it.
2908 */
2909 if (pPrev)
2910 {
2911 pPrev->pNext = pCur->pNext;
2912 if (!pCur->pNext)
2913 pUVM->vm.s.ppAtStateNext = &pPrev->pNext;
2914 }
2915 else
2916 {
2917 pUVM->vm.s.pAtState = pCur->pNext;
2918 if (!pCur->pNext)
2919 pUVM->vm.s.ppAtStateNext = &pUVM->vm.s.pAtState;
2920 }
2921
2922 /*
2923 * Free it.
2924 */
2925 pCur->pfnAtState = NULL;
2926 pCur->pNext = NULL;
2927 MMR3HeapFree(pCur);
2928
2929 return VINF_SUCCESS;
2930}
2931
2932
2933/**
2934 * Registers a VM error callback.
2935 *
2936 * @returns VBox status code.
2937 * @param pVM The VM handle.
2938 * @param pfnAtError Pointer to callback.
2939 * @param pvUser User argument.
2940 * @thread Any.
2941 */
2942VMMR3DECL(int) VMR3AtErrorRegister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser)
2943{
2944 return VMR3AtErrorRegisterU(pVM->pUVM, pfnAtError, pvUser);
2945}
2946
2947
2948/**
2949 * Registers a VM error callback.
2950 *
2951 * @returns VBox status code.
2952 * @param pUVM The VM handle.
2953 * @param pfnAtError Pointer to callback.
2954 * @param pvUser User argument.
2955 * @thread Any.
2956 */
2957VMMR3DECL(int) VMR3AtErrorRegisterU(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser)
2958{
2959 LogFlow(("VMR3AtErrorRegister: pfnAtError=%p pvUser=%p\n", pfnAtError, pvUser));
2960 AssertPtrReturn(pfnAtError, VERR_INVALID_PARAMETER);
2961
2962 /*
2963 * Make sure we're in EMT (to avoid the logging).
2964 */
2965 PVMREQ pReq;
2966 int rc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)vmR3AtErrorRegisterU, 3, pUVM, pfnAtError, pvUser);
2967 if (RT_FAILURE(rc))
2968 return rc;
2969 rc = pReq->iStatus;
2970 VMR3ReqFree(pReq);
2971
2972 LogFlow(("VMR3AtErrorRegister: returns %Rrc\n", rc));
2973 return rc;
2974}
2975
2976
2977/**
2978 * Registers a VM error callback.
2979 *
2980 * @returns VBox status code.
2981 * @param pUVM Pointer to the user mode VM structure.
2982 * @param pfnAtError Pointer to callback.
2983 * @param pvUser User argument.
2984 * @thread EMT
2985 */
2986static DECLCALLBACK(int) vmR3AtErrorRegisterU(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser)
2987{
2988 /*
2989 * Allocate a new record.
2990 */
2991
2992 PVMATERROR pNew = (PVMATERROR)MMR3HeapAllocU(pUVM, MM_TAG_VM, sizeof(*pNew));
2993 if (!pNew)
2994 return VERR_NO_MEMORY;
2995
2996 /* fill */
2997 pNew->pfnAtError = pfnAtError;
2998 pNew->pvUser = pvUser;
2999
3000 /* insert */
3001 pNew->pNext = *pUVM->vm.s.ppAtErrorNext;
3002 *pUVM->vm.s.ppAtErrorNext = pNew;
3003 pUVM->vm.s.ppAtErrorNext = &pNew->pNext;
3004
3005 return VINF_SUCCESS;
3006}
3007
3008
3009/**
3010 * Deregisters a VM error callback.
3011 *
3012 * @returns VBox status code.
3013 * @param pVM The VM handle.
3014 * @param pfnAtError Pointer to callback.
3015 * @param pvUser User argument.
3016 * @thread Any.
3017 */
3018VMMR3DECL(int) VMR3AtErrorDeregister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser)
3019{
3020 LogFlow(("VMR3AtErrorDeregister: pfnAtError=%p pvUser=%p\n", pfnAtError, pvUser));
3021
3022 /*
3023 * Validate input.
3024 */
3025 if (!pfnAtError)
3026 {
3027 AssertMsgFailed(("callback is required\n"));
3028 return VERR_INVALID_PARAMETER;
3029 }
3030
3031 /*
3032 * Make sure we're in EMT (to avoid the logging).
3033 */
3034 PVMREQ pReq;
3035 int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3AtErrorDeregisterU, 3, pVM->pUVM, pfnAtError, pvUser);
3036 if (RT_FAILURE(rc))
3037 return rc;
3038 rc = pReq->iStatus;
3039 VMR3ReqFree(pReq);
3040
3041 LogFlow(("VMR3AtErrorDeregister: returns %Rrc\n", rc));
3042 return rc;
3043}
3044
3045
3046/**
3047 * Deregisters a VM error callback.
3048 *
3049 * @returns VBox status code.
3050 * @param pUVM Pointer to the user mode VM structure.
3051 * @param pfnAtError Pointer to callback.
3052 * @param pvUser User argument.
3053 * @thread EMT
3054 */
3055static DECLCALLBACK(int) vmR3AtErrorDeregisterU(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser)
3056{
3057 LogFlow(("vmR3AtErrorDeregisterU: pfnAtError=%p pvUser=%p\n", pfnAtError, pvUser));
3058
3059 /*
3060 * Search the list for the entry.
3061 */
3062 PVMATERROR pPrev = NULL;
3063 PVMATERROR pCur = pUVM->vm.s.pAtError;
3064 while ( pCur
3065 && ( pCur->pfnAtError != pfnAtError
3066 || pCur->pvUser != pvUser))
3067 {
3068 pPrev = pCur;
3069 pCur = pCur->pNext;
3070 }
3071 if (!pCur)
3072 {
3073 AssertMsgFailed(("pfnAtError=%p was not found\n", pfnAtError));
3074 return VERR_FILE_NOT_FOUND;
3075 }
3076
3077 /*
3078 * Unlink it.
3079 */
3080 if (pPrev)
3081 {
3082 pPrev->pNext = pCur->pNext;
3083 if (!pCur->pNext)
3084 pUVM->vm.s.ppAtErrorNext = &pPrev->pNext;
3085 }
3086 else
3087 {
3088 pUVM->vm.s.pAtError = pCur->pNext;
3089 if (!pCur->pNext)
3090 pUVM->vm.s.ppAtErrorNext = &pUVM->vm.s.pAtError;
3091 }
3092
3093 /*
3094 * Free it.
3095 */
3096 pCur->pfnAtError = NULL;
3097 pCur->pNext = NULL;
3098 MMR3HeapFree(pCur);
3099
3100 return VINF_SUCCESS;
3101}
3102
3103
3104/**
3105 * Ellipsis to va_list wrapper for calling pfnAtError.
3106 */
3107static void vmR3SetErrorWorkerDoCall(PVM pVM, PVMATERROR pCur, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
3108{
3109 va_list va;
3110 va_start(va, pszFormat);
3111 pCur->pfnAtError(pVM, pCur->pvUser, rc, RT_SRC_POS_ARGS, pszFormat, va);
3112 va_end(va);
3113}
3114
3115
3116/**
3117 * This is a worker function for GC and Ring-0 calls to VMSetError and VMSetErrorV.
3118 * The message is found in VMINT.
3119 *
3120 * @param pVM The VM handle.
3121 * @thread EMT.
3122 */
3123VMMR3DECL(void) VMR3SetErrorWorker(PVM pVM)
3124{
3125 VM_ASSERT_EMT(pVM);
3126 AssertReleaseMsgFailed(("And we have a winner! You get to implement Ring-0 and GC VMSetErrorV! Contrats!\n"));
3127
3128 /*
3129 * Unpack the error (if we managed to format one).
3130 */
3131 PVMERROR pErr = pVM->vm.s.pErrorR3;
3132 const char *pszFile = NULL;
3133 const char *pszFunction = NULL;
3134 uint32_t iLine = 0;
3135 const char *pszMessage;
3136 int32_t rc = VERR_MM_HYPER_NO_MEMORY;
3137 if (pErr)
3138 {
3139 AssertCompile(sizeof(const char) == sizeof(uint8_t));
3140 if (pErr->offFile)
3141 pszFile = (const char *)pErr + pErr->offFile;
3142 iLine = pErr->iLine;
3143 if (pErr->offFunction)
3144 pszFunction = (const char *)pErr + pErr->offFunction;
3145 if (pErr->offMessage)
3146 pszMessage = (const char *)pErr + pErr->offMessage;
3147 else
3148 pszMessage = "No message!";
3149 }
3150 else
3151 pszMessage = "No message! (Failed to allocate memory to put the error message in!)";
3152
3153 /*
3154 * Call the at error callbacks.
3155 */
3156 for (PVMATERROR pCur = pVM->pUVM->vm.s.pAtError; pCur; pCur = pCur->pNext)
3157 vmR3SetErrorWorkerDoCall(pVM, pCur, rc, RT_SRC_POS_ARGS, "%s", pszMessage);
3158}
3159
3160
3161/**
3162 * Creation time wrapper for vmR3SetErrorUV.
3163 *
3164 * @returns rc.
3165 * @param pUVM Pointer to the user mode VM structure.
3166 * @param rc The VBox status code.
3167 * @param RT_SRC_POS_DECL The source position of this error.
3168 * @param pszFormat Format string.
3169 * @param ... The arguments.
3170 * @thread Any thread.
3171 */
3172static int vmR3SetErrorU(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
3173{
3174 va_list va;
3175 va_start(va, pszFormat);
3176 vmR3SetErrorUV(pUVM, rc, pszFile, iLine, pszFunction, pszFormat, &va);
3177 va_end(va);
3178 return rc;
3179}
3180
3181
3182/**
3183 * Worker which calls everyone listening to the VM error messages.
3184 *
3185 * @param pUVM Pointer to the user mode VM structure.
3186 * @param rc The VBox status code.
3187 * @param RT_SRC_POS_DECL The source position of this error.
3188 * @param pszFormat Format string.
3189 * @param pArgs Pointer to the format arguments.
3190 * @thread EMT
3191 */
3192DECLCALLBACK(void) vmR3SetErrorUV(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list *pArgs)
3193{
3194#ifdef LOG_ENABLED
3195 /*
3196 * Log the error.
3197 */
3198 RTLogPrintf("VMSetError: %s(%d) %s\n", pszFile, iLine, pszFunction);
3199 va_list va3;
3200 va_copy(va3, *pArgs);
3201 RTLogPrintfV(pszFormat, va3);
3202 va_end(va3);
3203 RTLogPrintf("\n");
3204#endif
3205
3206 /*
3207 * Make a copy of the message.
3208 */
3209 if (pUVM->pVM)
3210 vmSetErrorCopy(pUVM->pVM, rc, RT_SRC_POS_ARGS, pszFormat, *pArgs);
3211
3212 /*
3213 * Call the at error callbacks.
3214 */
3215 for (PVMATERROR pCur = pUVM->vm.s.pAtError; pCur; pCur = pCur->pNext)
3216 {
3217 va_list va2;
3218 va_copy(va2, *pArgs);
3219 pCur->pfnAtError(pUVM->pVM, pCur->pvUser, rc, RT_SRC_POS_ARGS, pszFormat, va2);
3220 va_end(va2);
3221 }
3222}
3223
3224
3225/**
3226 * Registers a VM runtime error callback.
3227 *
3228 * @returns VBox status code.
3229 * @param pVM The VM handle.
3230 * @param pfnAtRuntimeError Pointer to callback.
3231 * @param pvUser User argument.
3232 * @thread Any.
3233 */
3234VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser)
3235{
3236 LogFlow(("VMR3AtRuntimeErrorRegister: pfnAtRuntimeError=%p pvUser=%p\n", pfnAtRuntimeError, pvUser));
3237
3238 /*
3239 * Validate input.
3240 */
3241 if (!pfnAtRuntimeError)
3242 {
3243 AssertMsgFailed(("callback is required\n"));
3244 return VERR_INVALID_PARAMETER;
3245 }
3246
3247 /*
3248 * Make sure we're in EMT (to avoid the logging).
3249 */
3250 PVMREQ pReq;
3251 int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3AtRuntimeErrorRegisterU, 3, pVM->pUVM, pfnAtRuntimeError, pvUser);
3252 if (RT_FAILURE(rc))
3253 return rc;
3254 rc = pReq->iStatus;
3255 VMR3ReqFree(pReq);
3256
3257 LogFlow(("VMR3AtRuntimeErrorRegister: returns %Rrc\n", rc));
3258 return rc;
3259}
3260
3261
3262/**
3263 * Registers a VM runtime error callback.
3264 *
3265 * @returns VBox status code.
3266 * @param pUVM Pointer to the user mode VM structure.
3267 * @param pfnAtRuntimeError Pointer to callback.
3268 * @param pvUser User argument.
3269 * @thread EMT
3270 */
3271static DECLCALLBACK(int) vmR3AtRuntimeErrorRegisterU(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser)
3272{
3273 /*
3274 * Allocate a new record.
3275 */
3276
3277 PVMATRUNTIMEERROR pNew = (PVMATRUNTIMEERROR)MMR3HeapAllocU(pUVM, MM_TAG_VM, sizeof(*pNew));
3278 if (!pNew)
3279 return VERR_NO_MEMORY;
3280
3281 /* fill */
3282 pNew->pfnAtRuntimeError = pfnAtRuntimeError;
3283 pNew->pvUser = pvUser;
3284
3285 /* insert */
3286 pNew->pNext = *pUVM->vm.s.ppAtRuntimeErrorNext;
3287 *pUVM->vm.s.ppAtRuntimeErrorNext = pNew;
3288 pUVM->vm.s.ppAtRuntimeErrorNext = &pNew->pNext;
3289
3290 return VINF_SUCCESS;
3291}
3292
3293
3294/**
3295 * Deregisters a VM runtime error callback.
3296 *
3297 * @returns VBox status code.
3298 * @param pVM The VM handle.
3299 * @param pfnAtRuntimeError Pointer to callback.
3300 * @param pvUser User argument.
3301 * @thread Any.
3302 */
3303VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser)
3304{
3305 LogFlow(("VMR3AtRuntimeErrorDeregister: pfnAtRuntimeError=%p pvUser=%p\n", pfnAtRuntimeError, pvUser));
3306
3307 /*
3308 * Validate input.
3309 */
3310 if (!pfnAtRuntimeError)
3311 {
3312 AssertMsgFailed(("callback is required\n"));
3313 return VERR_INVALID_PARAMETER;
3314 }
3315
3316 /*
3317 * Make sure we're in EMT (to avoid the logging).
3318 */
3319 PVMREQ pReq;
3320 int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3AtRuntimeErrorDeregisterU, 3, pVM->pUVM, pfnAtRuntimeError, pvUser);
3321 if (RT_FAILURE(rc))
3322 return rc;
3323 rc = pReq->iStatus;
3324 VMR3ReqFree(pReq);
3325
3326 LogFlow(("VMR3AtRuntimeErrorDeregister: returns %Rrc\n", rc));
3327 return rc;
3328}
3329
3330
3331/**
3332 * Deregisters a VM runtime error callback.
3333 *
3334 * @returns VBox status code.
3335 * @param pUVM Pointer to the user mode VM structure.
3336 * @param pfnAtRuntimeError Pointer to callback.
3337 * @param pvUser User argument.
3338 * @thread EMT
3339 */
3340static DECLCALLBACK(int) vmR3AtRuntimeErrorDeregisterU(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser)
3341{
3342 LogFlow(("vmR3AtRuntimeErrorDeregisterU: pfnAtRuntimeError=%p pvUser=%p\n", pfnAtRuntimeError, pvUser));
3343
3344 /*
3345 * Search the list for the entry.
3346 */
3347 PVMATRUNTIMEERROR pPrev = NULL;
3348 PVMATRUNTIMEERROR pCur = pUVM->vm.s.pAtRuntimeError;
3349 while ( pCur
3350 && ( pCur->pfnAtRuntimeError != pfnAtRuntimeError
3351 || pCur->pvUser != pvUser))
3352 {
3353 pPrev = pCur;
3354 pCur = pCur->pNext;
3355 }
3356 if (!pCur)
3357 {
3358 AssertMsgFailed(("pfnAtRuntimeError=%p was not found\n", pfnAtRuntimeError));
3359 return VERR_FILE_NOT_FOUND;
3360 }
3361
3362 /*
3363 * Unlink it.
3364 */
3365 if (pPrev)
3366 {
3367 pPrev->pNext = pCur->pNext;
3368 if (!pCur->pNext)
3369 pUVM->vm.s.ppAtRuntimeErrorNext = &pPrev->pNext;
3370 }
3371 else
3372 {
3373 pUVM->vm.s.pAtRuntimeError = pCur->pNext;
3374 if (!pCur->pNext)
3375 pUVM->vm.s.ppAtRuntimeErrorNext = &pUVM->vm.s.pAtRuntimeError;
3376 }
3377
3378 /*
3379 * Free it.
3380 */
3381 pCur->pfnAtRuntimeError = NULL;
3382 pCur->pNext = NULL;
3383 MMR3HeapFree(pCur);
3384
3385 return VINF_SUCCESS;
3386}
3387
3388
3389/**
3390 * Worker for VMR3SetRuntimeErrorWorker and vmR3SetRuntimeErrorV.
3391 *
3392 * This does the common parts after the error has been saved / retrieved.
3393 *
3394 * @returns VBox status code with modifications, see VMSetRuntimeErrorV.
3395 *
3396 * @param pVM The VM handle.
3397 * @param fFlags The error flags.
3398 * @param pszErrorId Error ID string.
3399 * @param pszFormat Format string.
3400 * @param pVa Pointer to the format arguments.
3401 */
3402static int vmR3SetRuntimeErrorCommon(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa)
3403{
3404 LogRel(("VM: Raising runtime error '%s' (fFlags=%#x)\n", pszErrorId, fFlags));
3405
3406 /*
3407 * Take actions before the call.
3408 */
3409 int rc = VINF_SUCCESS;
3410 if (fFlags & VMSETRTERR_FLAGS_FATAL)
3411 /** @todo Add some special VM state for the FATAL variant that isn't resumable.
3412 * It's too risky for 2.2.0, do after branching. */
3413 rc = VMR3SuspendNoSave(pVM);
3414 else if (fFlags & VMSETRTERR_FLAGS_SUSPEND)
3415 rc = VMR3Suspend(pVM);
3416
3417 /*
3418 * Do the callback round.
3419 */
3420 for (PVMATRUNTIMEERROR pCur = pVM->pUVM->vm.s.pAtRuntimeError; pCur; pCur = pCur->pNext)
3421 {
3422 va_list va;
3423 va_copy(va, *pVa);
3424 pCur->pfnAtRuntimeError(pVM, pCur->pvUser, fFlags, pszErrorId, pszFormat, va);
3425 va_end(va);
3426 }
3427
3428 return rc;
3429}
3430
3431
3432/**
3433 * Ellipsis to va_list wrapper for calling vmR3SetRuntimeErrorCommon.
3434 */
3435static int vmR3SetRuntimeErrorCommonF(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
3436{
3437 va_list va;
3438 va_start(va, pszFormat);
3439 int rc = vmR3SetRuntimeErrorCommon(pVM, fFlags, pszErrorId, pszFormat, &va);
3440 va_end(va);
3441 return rc;
3442}
3443
3444
3445/**
3446 * This is a worker function for RC and Ring-0 calls to VMSetError and
3447 * VMSetErrorV.
3448 *
3449 * The message is found in VMINT.
3450 *
3451 * @returns VBox status code, see VMSetRuntimeError.
3452 * @param pVM The VM handle.
3453 * @thread EMT.
3454 */
3455VMMR3DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM)
3456{
3457 VM_ASSERT_EMT(pVM);
3458 AssertReleaseMsgFailed(("And we have a winner! You get to implement Ring-0 and GC VMSetRuntimeErrorV! Congrats!\n"));
3459
3460 /*
3461 * Unpack the error (if we managed to format one).
3462 */
3463 const char *pszErrorId = "SetRuntimeError";
3464 const char *pszMessage = "No message!";
3465 uint32_t fFlags = VMSETRTERR_FLAGS_FATAL;
3466 PVMRUNTIMEERROR pErr = pVM->vm.s.pRuntimeErrorR3;
3467 if (pErr)
3468 {
3469 AssertCompile(sizeof(const char) == sizeof(uint8_t));
3470 if (pErr->offErrorId)
3471 pszErrorId = (const char *)pErr + pErr->offErrorId;
3472 if (pErr->offMessage)
3473 pszMessage = (const char *)pErr + pErr->offMessage;
3474 fFlags = pErr->fFlags;
3475 }
3476
3477 /*
3478 * Join cause with vmR3SetRuntimeErrorV.
3479 */
3480 return vmR3SetRuntimeErrorCommonF(pVM, fFlags, pszErrorId, "%s", pszMessage);
3481}
3482
3483
3484/**
3485 * Worker for VMSetRuntimeErrorV for doing the job on EMT in ring-3.
3486 *
3487 * @returns VBox status code with modifications, see VMSetRuntimeErrorV.
3488 *
3489 * @param pVM The VM handle.
3490 * @param fFlags The error flags.
3491 * @param pszErrorId Error ID string.
3492 * @param pszFormat Format string.
3493 * @param pVa Pointer to the format arguments.
3494 *
3495 * @thread EMT
3496 */
3497DECLCALLBACK(int) vmR3SetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa)
3498{
3499 /*
3500 * Make a copy of the message.
3501 */
3502 va_list va2;
3503 va_copy(va2, *pVa);
3504 vmSetRuntimeErrorCopy(pVM, fFlags, pszErrorId, pszFormat, va2);
3505 va_end(va2);
3506
3507 /*
3508 * Join paths with VMR3SetRuntimeErrorWorker.
3509 */
3510 return vmR3SetRuntimeErrorCommon(pVM, fFlags, pszErrorId, pszFormat, pVa);
3511}
3512
3513
3514/**
3515 * Gets the ID virtual of the virtual CPU assoicated with the calling thread.
3516 *
3517 * @returns The CPU ID. NIL_VMCPUID if the thread isn't an EMT.
3518 *
3519 * @param pVM The VM handle.
3520 */
3521VMMR3DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM)
3522{
3523 PUVMCPU pUVCpu = (PUVMCPU)RTTlsGet(pVM->pUVM->vm.s.idxTLS);
3524 return pUVCpu
3525 ? pUVCpu->idCpu
3526 : NIL_VMCPUID;
3527}
3528
3529
3530/**
3531 * Returns the native handle of the current EMT VMCPU thread.
3532 *
3533 * @returns Handle if this is an EMT thread; NIL_RTNATIVETHREAD otherwise
3534 * @param pVM The VM handle.
3535 * @thread EMT
3536 */
3537VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThread(PVM pVM)
3538{
3539 PUVMCPU pUVCpu = (PUVMCPU)RTTlsGet(pVM->pUVM->vm.s.idxTLS);
3540
3541 if (!pUVCpu)
3542 return NIL_RTNATIVETHREAD;
3543
3544 return pUVCpu->vm.s.NativeThreadEMT;
3545}
3546
3547
3548/**
3549 * Returns the native handle of the current EMT VMCPU thread.
3550 *
3551 * @returns Handle if this is an EMT thread; NIL_RTNATIVETHREAD otherwise
3552 * @param pVM The VM handle.
3553 * @thread EMT
3554 */
3555VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThreadU(PUVM pUVM)
3556{
3557 PUVMCPU pUVCpu = (PUVMCPU)RTTlsGet(pUVM->vm.s.idxTLS);
3558
3559 if (!pUVCpu)
3560 return NIL_RTNATIVETHREAD;
3561
3562 return pUVCpu->vm.s.NativeThreadEMT;
3563}
3564
3565
3566/**
3567 * Returns the handle of the current EMT VMCPU thread.
3568 *
3569 * @returns Handle if this is an EMT thread; NIL_RTNATIVETHREAD otherwise
3570 * @param pVM The VM handle.
3571 * @thread EMT
3572 */
3573VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PVM pVM)
3574{
3575 PUVMCPU pUVCpu = (PUVMCPU)RTTlsGet(pVM->pUVM->vm.s.idxTLS);
3576
3577 if (!pUVCpu)
3578 return NIL_RTTHREAD;
3579
3580 return pUVCpu->vm.s.ThreadEMT;
3581}
3582
3583
3584/**
3585 * Returns the handle of the current EMT VMCPU thread.
3586 *
3587 * @returns Handle if this is an EMT thread; NIL_RTNATIVETHREAD otherwise
3588 * @param pVM The VM handle.
3589 * @thread EMT
3590 */
3591VMMR3DECL(RTTHREAD) VMR3GetVMCPUThreadU(PUVM pUVM)
3592{
3593 PUVMCPU pUVCpu = (PUVMCPU)RTTlsGet(pUVM->vm.s.idxTLS);
3594
3595 if (!pUVCpu)
3596 return NIL_RTTHREAD;
3597
3598 return pUVCpu->vm.s.ThreadEMT;
3599}
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