VirtualBox

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

Last change on this file since 61574 was 61570, checked in by vboxsync, 9 years ago

DBGFR3Info*: Added DBGFINFO_FLAGS_ALL_EMTS flag for cpum, apic and others dealing with per-vcpu state. Also got rid of some redundant VMR3ReqCallWaitU calls when we're already on the rigth EMT, and replacing them with priority calls when we actually need them. Didn't make sense to only do priority calls from DBGFR3InfoEx.

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

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