• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <sys/cdefs.h>
22 #include <time.h>
23 
24 __BEGIN_DECLS
25 
26 /**
27  * Represents a handle on a virtual machine raw config.
28  */
29 typedef struct AVirtualMachineRawConfig AVirtualMachineRawConfig;
30 
31 /**
32  * Create a new virtual machine raw config object with no properties.
33  *
34  * This only creates the raw config object. `name` and `kernel` must be set with
35  * calls to {@link AVirtualMachineRawConfig_setName} and {@link AVirtualMachineRawConfig_setKernel}.
36  * Other properties, set by {@link AVirtualMachineRawConfig_setMemoryMiB},
37  * {@link AVirtualMachineRawConfig_setInitRd}, {@link AVirtualMachineRawConfig_addDisk},
38  * {@link AVirtualMachineRawConfig_setProtectedVm}, and {@link AVirtualMachineRawConfig_setBalloon}
39  * are optional.
40  *
41  * The caller takes ownership of the returned raw config object, and is responsible for creating a
42  * VM by calling {@link AVirtualMachine_createRaw} or releasing it by calling
43  * {@link AVirtualMachineRawConfig_destroy}.
44  *
45  * \return A new virtual machine raw config object. On failure (such as out of memory), it aborts.
46  */
47 AVirtualMachineRawConfig* _Nonnull AVirtualMachineRawConfig_create(void) __INTRODUCED_IN(36);
48 
49 /**
50  * Destroy a virtual machine config object.
51  *
52  * \param config a virtual machine config object.
53  *
54  * `AVirtualMachineRawConfig_destroy` does nothing if `config` is null. A destroyed config object
55  * must not be reused.
56  */
57 void AVirtualMachineRawConfig_destroy(AVirtualMachineRawConfig* _Nullable config)
58         __INTRODUCED_IN(36);
59 
60 /**
61  * Set a name of a virtual machine.
62  *
63  * \param config a virtual machine config object.
64  * \param name a pointer to a null-terminated, UTF-8 encoded string for the name.
65  *
66  * \return If successful, it returns 0. If `name` is not a null-terminated UTF-8 encoded string,
67  *   it returns -EINVAL.
68  */
69 int AVirtualMachineRawConfig_setName(AVirtualMachineRawConfig* _Nonnull config,
70                                      const char* _Nonnull name) __INTRODUCED_IN(36);
71 
72 /**
73  * Set an instance ID of a virtual machine. Every virtual machine is identified by a unique
74  * `instanceId` which the virtual machine uses as its persistent identity while performing stateful
75  * operations that are expected to outlast single boot of the VM. For example, some virtual machines
76  * use it as a `Id` for storing secrets in Secretkeeper, which are retrieved on next boot of th VM.
77  *
78  * The `instanceId` is expected to be re-used for the VM instance with an associated state (secret,
79  * encrypted storage) - i.e., rebooting the VM must not change the instanceId.
80  *
81  * `instanceId` MUST start with 0xFFFFFFFF if and only if this library is being
82  * called from code in a vendor or odm partition,
83  *
84  * \param config a virtual machine config object.
85  * \param instanceId a pointer to a 64-byte buffer for the instance ID.
86  * \param instanceIdSize the number of bytes in `instanceId`.
87  *
88  * \return If successful, it returns 0. If `instanceIdSize` is incorrect, it returns -EINVAL.
89  */
90 int AVirtualMachineRawConfig_setInstanceId(AVirtualMachineRawConfig* _Nonnull config,
91                                            const uint8_t* _Nonnull instanceId,
92                                            size_t instanceIdSize) __INTRODUCED_IN(36);
93 
94 /**
95  * Set a kernel image of a virtual machine.
96  *
97  * \param config a virtual machine config object.
98  * \param fd a readable, seekable, and sized (i.e. report a valid size using fstat()) file
99  *   descriptor containing the kernel image, or -1 to unset. `AVirtualMachineRawConfig_setKernel`
100  *   takes ownership of `fd`.
101  */
102 void AVirtualMachineRawConfig_setKernel(AVirtualMachineRawConfig* _Nonnull config, int fd)
103         __INTRODUCED_IN(36);
104 
105 /**
106  * Set an init rd of a virtual machine.
107  *
108  * \param config a virtual machine config object.
109  * \param fd a readable, seekable, and sized (i.e. report a valid size using fstat()) file
110  *   descriptor containing the init rd image, or -1 to unset. `AVirtualMachineRawConfig_setInitRd`
111  *   takes ownership of `fd`.
112  */
113 void AVirtualMachineRawConfig_setInitRd(AVirtualMachineRawConfig* _Nonnull config, int fd)
114         __INTRODUCED_IN(36);
115 
116 /**
117  * Add a disk for a virtual machine.
118  *
119  * \param config a virtual machine config object.
120  * \param fd a readable, seekable, and sized (i.e. report a valid size using fstat()) file
121  *   descriptor containing the disk. `fd` must be writable if If `writable` is true.
122  *   `AVirtualMachineRawConfig_addDisk` takes ownership of `fd`.
123  * \param writable whether this disk should be writable by the virtual machine.
124  *
125  * \return If successful, it returns 0. If `fd` is invalid, it returns -EINVAL.
126  */
127 int AVirtualMachineRawConfig_addDisk(AVirtualMachineRawConfig* _Nonnull config, int fd,
128                                      bool writable) __INTRODUCED_IN(36);
129 
130 /**
131  * Set how much memory will be given to a virtual machine.
132  *
133  * When `AVirtualMachineRawConfig_setProtectedVm(..., true)` is set, the memory
134  * size provided here will be automatically augmented with the swiotlb size.
135  *
136  * \param config a virtual machine config object.
137  * \param memoryMiB the amount of RAM to give the virtual machine, in MiB. 0 or negative to use the
138  *   default.
139  */
140 void AVirtualMachineRawConfig_setMemoryMiB(AVirtualMachineRawConfig* _Nonnull config,
141                                            int32_t memoryMiB) __INTRODUCED_IN(36);
142 
143 /**
144  * Set how much swiotlb will be given to a virtual machine.
145  *
146  * Only applicable when `AVirtualMachineRawConfig_setProtectedVm(..., true)` is
147  * set.
148  *
149  * For information on swiotlb, see https://docs.kernel.org/core-api/swiotlb.html.
150  *
151  * \param config a virtual machine config object.
152  * \param memoryMiB the amount of swiotlb to give the virtual machine, in MiB.
153  *   0 or negative to use the default.
154  */
155 void AVirtualMachineRawConfig_setSwiotlbMiB(AVirtualMachineRawConfig* _Nonnull config,
156                                             int32_t swiotlbMiB) __INTRODUCED_IN(36);
157 
158 /**
159  * Set vCPU count. The default is 1.
160  *
161  * \param config a virtual machine config object.
162  * \param n number of vCPUs. Must be positive.
163  */
164 void AVirtualMachineRawConfig_setVCpuCount(AVirtualMachineRawConfig* _Nonnull config, int32_t n)
165         __INTRODUCED_IN(36);
166 
167 /**
168  * Set whether the virtual machine's memory will be protected from the host, so the host can't
169  * access its memory.
170  *
171  * \param config a virtual machine config object.
172  * \param protectedVm whether the virtual machine should be protected.
173  */
174 void AVirtualMachineRawConfig_setProtectedVm(AVirtualMachineRawConfig* _Nonnull config,
175                                              bool protectedVm) __INTRODUCED_IN(36);
176 
177 /**
178  * Set whether to use an alternate, hypervisor-specific authentication method
179  * for protected VMs.
180  *
181  * This option is discouraged. Prefer to use the default authentication method, which is better
182  * tested and integrated into Android. This option must only be used from the vendor partition.
183  *
184  * \return If successful, it returns 0. It returns `-ENOTSUP` if the hypervisor doesn't have an
185  *   alternate auth mode.
186  */
187 int AVirtualMachineRawConfig_setHypervisorSpecificAuthMethod(
188         AVirtualMachineRawConfig* _Nonnull config, bool enable) __INTRODUCED_IN(36);
189 
190 /**
191  * Use the specified fd as the backing memfd for a range of the guest
192  * physical memory.
193  *
194  * \param config a virtual machine config object.
195  * \param fd a memfd. Ownership is transferred, even if the function is not successful.
196  * \param rangeStart range start of guest memory addresses
197  * \param rangeEnd range end of guest memory addresses
198  *
199  * \return If successful, it returns 0. It returns `-ENOTSUP` if the hypervisor doesn't support
200  *   backing memfd.
201  */
202 int AVirtualMachineRawConfig_addCustomMemoryBackingFile(AVirtualMachineRawConfig* _Nonnull config,
203                                                         int fd, uint64_t rangeStart,
204                                                         uint64_t rangeEnd) __INTRODUCED_IN(36);
205 /**
206  * Use the specified fd as the device tree overlay blob for booting VM.
207  *
208  * Here's the format of the device tree overlay blob.
209  * link: https://source.android.com/docs/core/architecture/dto
210  *
211  * \param config a virtual machine config object.
212  * \param fd a readable, seekable, and sized (i.e. report a valid size using fstat()) file
213  *   descriptor containing device tree overlay, or -1 to unset.
214  *   `AVirtualMachineRawConfig_setDeviceTreeOverlay` takes ownership of `fd`.
215  */
216 void AVirtualMachineRawConfig_setDeviceTreeOverlay(AVirtualMachineRawConfig* _Nonnull config,
217                                                    int fd) __INTRODUCED_IN(36);
218 
219 /**
220  * Represents a handle on a virtualization service, responsible for managing virtual machines.
221  */
222 typedef struct AVirtualizationService AVirtualizationService;
223 
224 /**
225  * Spawn a new instance of `virtmgr`, a child process that will host the `VirtualizationService`
226  * service, and connect to the child process.
227  *
228  * The caller takes ownership of the returned service object, and is responsible for releasing it
229  * by calling {@link AVirtualizationService_destroy}.
230  *
231  * \param early set to true when running a service for early virtual machines. Early VMs are
232  *   specialized virtual machines that can run even before the `/data` partition is mounted.
233  *   Early VMs must be pre-defined in XML files located at `{partition}/etc/avf/early_vms*.xml`, and
234  *   clients of early VMs must be pre-installed under the same partition.
235  * \param service an out parameter that will be set to the service handle.
236  *
237  * \return
238  *   - If successful, it sets `service` and returns 0.
239  *   - If it fails to spawn `virtmgr`, it leaves `service` untouched and returns a negative value
240  *     representing the OS error code.
241  *   - If it fails to connect to the spawned `virtmgr`, it leaves `service` untouched and returns
242  *     `-ECONNREFUSED`.
243  */
244 int AVirtualizationService_create(AVirtualizationService* _Null_unspecified* _Nonnull service,
245                                   bool early) __INTRODUCED_IN(36);
246 
247 /**
248  * Destroy a VirtualizationService object.
249  *
250  * `AVirtualizationService_destroy` does nothing if `service` is null. A destroyed service object
251  * must not be reused.
252  *
253  * \param service a handle on a virtualization service.
254  */
255 void AVirtualizationService_destroy(AVirtualizationService* _Nullable service) __INTRODUCED_IN(36);
256 
257 /**
258  * Represents a handle on a virtual machine.
259  */
260 typedef struct AVirtualMachine AVirtualMachine;
261 
262 /**
263  * The reason why a virtual machine stopped.
264  * @see AVirtualMachine_waitForStop
265  */
266 enum AVirtualMachineStopReason : int32_t {
267     /**
268      * VirtualizationService died.
269      */
270     AVIRTUAL_MACHINE_VIRTUALIZATION_SERVICE_DIED = 1,
271     /**
272      * There was an error waiting for the virtual machine.
273      */
274     AVIRTUAL_MACHINE_INFRASTRUCTURE_ERROR = 2,
275     /**
276      * The virtual machine was killed.
277      */
278     AVIRTUAL_MACHINE_KILLED = 3,
279     /**
280      * The virtual machine stopped for an unknown reason.
281      */
282     AVIRTUAL_MACHINE_UNKNOWN = 4,
283     /**
284      * The virtual machine requested to shut down.
285      */
286     AVIRTUAL_MACHINE_SHUTDOWN = 5,
287     /**
288      * crosvm had an error starting the virtual machine.
289      */
290     AVIRTUAL_MACHINE_START_FAILED = 6,
291     /**
292      * The virtual machine requested to reboot, possibly as the result of a kernel panic.
293      */
294     AVIRTUAL_MACHINE_REBOOT = 7,
295     /**
296      * The virtual machine or crosvm crashed.
297      */
298     AVIRTUAL_MACHINE_CRASH = 8,
299     /**
300      * The pVM firmware failed to verify the VM because the public key doesn't match.
301      */
302     AVIRTUAL_MACHINE_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH = 9,
303     /**
304      * The pVM firmware failed to verify the VM because the instance image changed.
305      */
306     AVIRTUAL_MACHINE_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED = 10,
307     /**
308      * The virtual machine was killed due to hangup.
309      */
310     AVIRTUAL_MACHINE_HANGUP = 11,
311     /**
312      * VirtualizationService sent a stop reason which was not recognised by the client library.
313      */
314     AVIRTUAL_MACHINE_UNRECOGNISED = 0,
315 };
316 
317 /**
318  * Create a virtual machine with given raw `config`.
319  *
320  * The created virtual machine is in stopped state. To run the created virtual machine, call
321  * {@link AVirtualMachine_start}.
322  *
323  * The caller takes ownership of the returned virtual machine object, and is responsible for
324  * releasing it by calling {@link AVirtualMachine_destroy}.
325  *
326  * \param service a handle on a virtualization service.
327  * \param config a virtual machine config object. Ownership will always be transferred from the
328  *   caller, even if unsuccessful. `config` must not be reused.
329  * \param consoleOutFd a writable file descriptor for the console output, or -1. Ownership will
330  *   always be transferred from the caller, even if unsuccessful.
331  * \param consoleInFd a readable file descriptor for the console input, or -1. Ownership will always
332  *   be transferred from the caller, even if unsuccessful.
333  * \param logFd a writable file descriptor for the log output, or -1. Ownership will always be
334  *   transferred from the caller, even if unsuccessful.
335  * \param vm an out parameter that will be set to the virtual machine handle.
336  *
337  * \return If successful, it sets `vm` and returns 0. Otherwise, it leaves `vm` untouched and
338  *   returns `-EIO`.
339  */
340 int AVirtualMachine_createRaw(const AVirtualizationService* _Nonnull service,
341                               AVirtualMachineRawConfig* _Nonnull config, int consoleOutFd,
342                               int consoleInFd, int logFd,
343                               AVirtualMachine* _Null_unspecified* _Nonnull vm) __INTRODUCED_IN(36);
344 
345 /**
346  * Start a virtual machine. `AVirtualMachine_start` is synchronous and blocks until the virtual
347  * machine is initialized and free to start executing code, or until an error happens.
348  *
349  * \param vm a handle on a virtual machine.
350  *
351  * \return If successful, it returns 0. Otherwise, it returns `-EIO`.
352  */
353 int AVirtualMachine_start(AVirtualMachine* _Nonnull vm) __INTRODUCED_IN(36);
354 
355 /**
356  * Stop a virtual machine. Stopping a virtual machine is like pulling the plug on a real computer;
357  * the machine halts immediately. Software running on the virtual machine is not notified of the
358  * event, the instance might be left in an inconsistent state.
359  *
360  * For a graceful shutdown, you could request the virtual machine to exit itself, and wait for the
361  * virtual machine to stop by `AVirtualMachine_waitForStop`.
362  *
363  * A stopped virtual machine cannot be re-started.
364  *
365  * `AVirtualMachine_stop` stops a virtual machine by sending a signal to the process. This operation
366  * is synchronous and `AVirtualMachine_stop` may block.
367  *
368  * \param vm a handle on a virtual machine.
369  *
370  * \return If successful, it returns 0. Otherwise, it returns `-EIO`.
371  */
372 int AVirtualMachine_stop(AVirtualMachine* _Nonnull vm) __INTRODUCED_IN(36);
373 
374 /**
375  * Open a vsock connection to the VM on the given port. The caller takes ownership of the returned
376  * file descriptor, and is responsible for closing the file descriptor.
377  *
378  * This operation is synchronous and `AVirtualMachine_connectVsock` may block.
379  *
380  * \param vm a handle on a virtual machine.
381  * \param port a vsock port number.
382  *
383  * \return If successful, it returns a valid file descriptor. Otherwise, it returns `-EIO`.
384  */
385 int AVirtualMachine_connectVsock(AVirtualMachine* _Nonnull vm, uint32_t port) __INTRODUCED_IN(36);
386 
387 /**
388  * Wait until a virtual machine stops or the given timeout elapses.
389  *
390  * \param vm a handle on a virtual machine.
391  * \param timeout the timeout, or null to wait indefinitely.
392  * \param reason An out parameter that will be set to the reason why the virtual machine stopped.
393  *
394  * \return
395  *   - If the virtual machine stops within the timeout (or indefinitely if `timeout` is null), it
396  *     sets `reason` and returns true.
397  *   - If the timeout expired, it returns `false`.
398  */
399 bool AVirtualMachine_waitForStop(AVirtualMachine* _Nonnull vm,
400                                  const struct timespec* _Nullable timeout,
401                                  enum AVirtualMachineStopReason* _Nonnull reason)
402         __INTRODUCED_IN(36);
403 
404 /**
405  * Destroy a virtual machine object. If the virtual machine is still running,
406  * `AVirtualMachine_destroy` first stops the virtual machine by sending a signal to the process.
407  * This operation is synchronous and `AVirtualMachine_destroy` may block.
408  *
409  * `AVirtualMachine_destroy` does nothing if `vm` is null. A destroyed virtual machine must not be
410  * reused.
411  *
412  * \param vm a handle on a virtual machine.
413  */
414 void AVirtualMachine_destroy(AVirtualMachine* _Nullable vm) __INTRODUCED_IN(36);
415 
416 __END_DECLS
417