VirtualBox

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

Last change on this file since 25901 was 25838, checked in by vboxsync, 15 years ago

Address todos (changes the protocol for CPU ejection) and make it possible to load a ACPI DSDT from an external AML file

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

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