summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/Docs-Intro.cpp
blob: 43b08b80b2bc877f79d1e6f317c3c6c929c6744f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* $Id: Docs-Intro.cpp $ */
/** @file
 * This file contains the introduction to Main for developers.
 */

/*
 * Copyright (C) 2011-2023 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * SPDX-License-Identifier: GPL-3.0-only
 */

/** @page pg_main       Main API
 *
 * First of all, check out the "Technical background" chapter in the manual, pay
 * attention to the "VirtualBox executables and components" chapter.  It lists
 * three processes, (1) VBoxSVC, (2) VirtualBox in manager mode and (3)
 * VirtualBox in VM mode.  This will be referred to as (1) server, (2) client
 * and (3) VM process, respectively.
 *
 *
 * @section sec_main_walk_thru_suspend  IConsole::Pause Walkthru
 *
 * The instigator can be a client (VirtualBox in manager mode, VBoxManage
 * controlvm, web services, ++) or the VM process it self (i.e. you select
 * pause via the menu or the host key short cut).
 *
 * We will not cover the case where the guest triggers a suspend.
 *
 * Approximate sequence of events:
 *  - Client calls IConsole::Pause.
 *  - The COM/XPCOM routes this to the VM process, invoking Console::Pause() in
 *    ConsoleImpl.cpp. (The IConsole::Pause method in the client process is a
 *    COM/XPCOM stub method which does marshalling+IPC.)
 *  - Console::Pause validates the Console object state, the VM state and the VM
 *    handle.
 *  - Console::Pause calls VMR3Suspend to do the actual suspending.
 *  - VMR3Suspend() in VMM/VMMR3/VM.cpp calls VMMR3EmtRendezvous() to change the
 *    VM state synchronously on all EMTs (threads performing as virtual CPUs).
 *  - VMMR3EmtRendezvous() will first detect that the caller isn't an EMT and
 *    use VMR3ReqCallWait() to forward the call to an EMT.
 *  - When VMMR3EmtRendezvous() is called again on an EMT, it will signal the
 *    other EMTs by raising a force action flag (VM_FF_EMT_RENDEZVOUS) and then
 *    poke them via VMR3NotifyGlobalFFU(). Then wait for them all to arrive.
 *  - The other EMTs will call VMMR3EmtRendezvousFF as soon as they can.
 *  - When all EMTs are there, the calling back of vmR3Suspend() on each CPU in
 *    decending order will start.
 *  - When the CPU with the higest ID calls vmR3Suspend() the VM state is
 *    changed to VMSTATE_SUSPENDING or VMSTATE_SUSPENDING_EXT_LS.
 *  - When the CPU with ID 0 calls vmR3Suspend() the virtual device emulations
 *    and drivers get notified via PDMR3Suspend().
 *  - PDMR3Suspend() in VMM/VMMR3/PDM.cpp will iterate thru all device
 *    emulations and notify them that the VM is suspending by calling their
 *    PDMDEVREG::pfnSuspend / PDMUSBREG::pfnSuspend entry point (can be NULL).
 *    For each device it will iterate the chains of drivers and call their
 *    PDMDRVREG::pfnSuspend entry point as well.
 *  - Should a worker thread in a PDM device or PDM driver be busy and need some
 *    extra time to finish up / notice the pending suspend, the device or driver
 *    will ask for more time via PDMDevHlpSetAsyncNotification(),
 *    PDMDrvHlpSetAsyncNotification() or PDMUsbHlpSetAsyncNotification().
 *    PDMR3Suspend will then poll these devices and drivers frequently until all
 *    are done.
 *  - PDMR3Suspend() will return to vmR3Suspend() once all PDM devices and PDM
 *    drivers has responded to the pfnSuspend callback.
 *  - The virtual CPU with ID 0 returns from vmR3Suspend() to the rendezvous
 *    code and the EMTs are released.
 *  - The inner VMMR3EmtRendezvous() call returns and this in turn triggers the
 *    VMR3ReqCallWait() call to return (with the status code of the inner call).
 *  - The outer VMMR3EmtRendezvous() returns to VMR3Suspend().
 *  - VMR3Suspend() returns to Console::Pause().
 *  - Console::Pause() checks the result and flags provides error details on
 *    failure.
 *  - Console::Pause() returns to the COM/XPCOM marshalling/IPC stuff.
 *  - Switch back to client process.
 *  - The IConsole::Pause() call returns. The end.
 *
 * Summary of above: Client process calls into the VM process, VM process does a
 * bunch of inter thread calls with all the EMT, EMT0 suspends the PDM devices
 * and drivers.
 *
 * The EMTs will return to the outer execution loop, vmR3EmulationThreadWithId()
 * in VMM/VMMR3/VMEmt.cpp, where they will mostly do sleep.  They will not
 * execute any guest code until VMR3Resume() is called.
 *
 */