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