VirtualBox

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

Last change on this file since 78431 was 78431, checked in by vboxsync, 6 years ago

VMM: Started refactoring GVM & VM structures for bugref:9217

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