1 /* 2 * Copyright (C) 2018-2022 Intel Corporation. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /** 8 * @file hypercall.h 9 * 10 * @brief public APIs for hypercall 11 */ 12 13 #ifndef HYPERCALL_H 14 #define HYPERCALL_H 15 16 bool is_hypercall_from_ring0(void); 17 18 /** 19 * @brief Hypercall 20 * 21 * @addtogroup acrn_hypercall ACRN Hypercall 22 * @{ 23 */ 24 25 /** 26 * @brief offline vcpu from Service VM 27 * 28 * The function offline specific vcpu from Service VM. 29 * 30 * @param vcpu Pointer to vCPU that initiates the hypercall 31 * @param target_vm not used 32 * @param param1 lapic id of the vcpu which wants to offline 33 * @param param2 not used 34 * 35 * @pre is_service_vm(vcpu->vm) 36 * @return 0 on success, non-zero on error. 37 */ 38 int32_t hcall_service_vm_offline_cpu(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 39 40 /** 41 * @brief Get hypervisor api version 42 * 43 * The function only return api version information when VM is Service VM. 44 * 45 * @param vcpu Pointer to vCPU that initiates the hypercall 46 * @param target_vm not used 47 * @param param1 guest physical memory address. The api version returned 48 * will be copied to this gpa 49 * @param param2 not used 50 * 51 * @pre is_service_vm(vcpu->vm) 52 * @return 0 on success, non-zero on error. 53 */ 54 int32_t hcall_get_api_version(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 55 56 57 /** 58 * @brief create virtual machine 59 * 60 * Create a virtual machine based on parameter, currently there is no 61 * limitation for calling times of this function, will add MAX_VM_NUM 62 * support later. 63 * 64 * @param vcpu Pointer to vCPU that initiates the hypercall 65 * @param target_vm Pointer to target VM data structure 66 * @param param1 guest physical memory address. This gpa points to 67 * struct acrn_vm_creation 68 * @param param2 not used 69 * 70 * @pre is_service_vm(vcpu->vm) 71 * @return 0 on success, non-zero on error. 72 */ 73 int32_t hcall_create_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 74 75 /** 76 * @brief destroy virtual machine 77 * 78 * Destroy a virtual machine, it will pause target VM then shutdown it. 79 * The function will return -1 if the target VM does not exist. 80 * 81 * @param vcpu not used 82 * @param target_vm Pointer to target VM data structure 83 * @param param1 not used 84 * @param param2 not used 85 * 86 * @return 0 on success, non-zero on error. 87 */ 88 int32_t hcall_destroy_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 89 90 /** 91 * @brief reset virtual machine 92 * 93 * Reset a virtual machine, it will make target VM rerun from 94 * pre-defined entry. Comparing to start vm, this function reset 95 * each vcpu state and do some initialization for guest. 96 * The function will return -1 if the target VM does not exist. 97 * 98 * @param vcpu not used 99 * @param target_vm Pointer to target VM data structure 100 * @param param1 not used 101 * @param param2 not used 102 * 103 * @return 0 on success, non-zero on error. 104 */ 105 int32_t hcall_reset_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 106 107 /** 108 * @brief start virtual machine 109 * 110 * Start a virtual machine, it will schedule target VM's vcpu to run. 111 * The function will return -1 if the target VM does not exist or the 112 * IOReq buffer page for the VM is not ready. 113 * 114 * @param vcpu not used 115 * @param target_vm Pointer to target VM data structure 116 * @param param1 not used 117 * @param param2 not used 118 * 119 * @return 0 on success, non-zero on error. 120 */ 121 int32_t hcall_start_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 122 123 /** 124 * @brief pause virtual machine 125 * 126 * Pause a virtual machine, if the VM is already paused, the function 127 * will return 0 directly for success. 128 * The function will return -1 if the target VM does not exist. 129 * 130 * @param vcpu not used 131 * @param target_vm Pointer to target VM data structure 132 * @param param1 not used 133 * @param param2 not used 134 * 135 * @return 0 on success, non-zero on error. 136 */ 137 int32_t hcall_pause_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 138 139 /** 140 * @brief set vcpu regs 141 * 142 * Set the vcpu regs. It will set the vcpu init regs from DM. Now, 143 * it's only applied to BSP. AP always uses fixed init regs. 144 * The function will return -1 if the targat VM or BSP doesn't exist. 145 * 146 * @param vcpu Pointer to vCPU that initiates the hypercall 147 * @param target_vm Pointer to target VM data structure 148 * @param param1 not used 149 * @param param2 guest physical address. This gpa points to 150 * struct acrn_vcpu_regs 151 * 152 * @return 0 on success, non-zero on error. 153 */ 154 int32_t hcall_set_vcpu_regs(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 155 156 /** 157 * @brief set or clear IRQ line 158 * 159 * Set or clear a virtual IRQ line for a VM, which could be from ISA 160 * or IOAPIC, normally it triggers an edge IRQ. 161 * The function will return -1 if the target VM does not exist. 162 * 163 * @param vcpu Pointer to vCPU that initiates the hypercall 164 * @param target_vm Pointer to target VM data structure 165 * @param param1 not used 166 * @param param2 info for irqline 167 * 168 * @pre is_service_vm(vcpu->vm) 169 * @return 0 on success, non-zero on error. 170 */ 171 int32_t hcall_set_irqline(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 172 173 /** 174 * @brief inject MSI interrupt 175 * 176 * Inject a MSI interrupt for a VM. 177 * The function will return -1 if the target VM does not exist. 178 * 179 * @param vcpu Pointer to vCPU that initiates the hypercall 180 * @param target_vm Pointer to target VM data structure 181 * @param param1 not used 182 * @param param2 guest physical address. This gpa points to struct acrn_msi_entry 183 * 184 * @pre is_service_vm(vcpu->vm) 185 * @return 0 on success, non-zero on error. 186 */ 187 int32_t hcall_inject_msi(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 188 189 /** 190 * @brief set ioreq shared buffer 191 * 192 * Set the ioreq share buffer for a VM. 193 * The function will return -1 if the target VM does not exist. 194 * 195 * @param vcpu Pointer to vCPU that initiates the hypercall 196 * @param target_vm Pointer to target VM data structure 197 * @param param1 not used 198 * @param param2 guest physical address. This gpa points to buffer address 199 * 200 * @pre is_service_vm(vcpu->vm) 201 * @return 0 on success, non-zero on error. 202 */ 203 int32_t hcall_set_ioreq_buffer(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 204 205 /** 206 * @brief notify request done 207 * 208 * Notify the requestor VCPU for the completion of an ioreq. 209 * The function will return -1 if the target VM does not exist. 210 * 211 * @param vcpu not used 212 * @param target_vm Pointer to target VM data structure 213 * @param param1 not used 214 * @param param2 vcpu ID of the requestor 215 * 216 * @return 0 on success, non-zero on error. 217 */ 218 int32_t hcall_notify_ioreq_finish(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 219 220 /** 221 * @brief setup ept memory mapping for multi regions 222 * 223 * @param vcpu Pointer to vCPU that initiates the hypercall 224 * @param target_vm Pointer to target VM data structure 225 * @param param1 guest physical address. This gpa points to 226 * struct set_memmaps 227 * @param param2 not used 228 * 229 * @pre is_service_vm(vcpu->vm) 230 * @return 0 on success, non-zero on error. 231 */ 232 int32_t hcall_set_vm_memory_regions(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, 233 uint64_t param1, uint64_t param2); 234 235 /** 236 * @brief change guest memory page write permission 237 * 238 * @param vcpu Pointer to vCPU that initiates the hypercall 239 * @param target_vm Pointer to target VM data structure 240 * @param param1 not used 241 * @param param2 guest physical address. This gpa points to 242 * struct wp_data 243 * 244 * @pre is_service_vm(vcpu->vm) 245 * @return 0 on success, non-zero on error. 246 */ 247 int32_t hcall_write_protect_page(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 248 249 /** 250 * @brief translate guest physical address to host physical address 251 * 252 * Translate guest physical address to host physical address for a VM. 253 * The function will return -1 if the target VM does not exist. 254 * 255 * @param vcpu Pointer to vCPU that initiates the hypercall 256 * @param target_vm Pointer to target VM data structure 257 * @param param1 not used 258 * @param param2 guest physical address. This gpa points to struct vm_gpa2hpa 259 * 260 * @pre is_service_vm(vcpu->vm) 261 * @return 0 on success, non-zero on error. 262 */ 263 int32_t hcall_gpa_to_hpa(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 264 265 /** 266 * @brief Assign one PCI dev to VM. 267 * 268 * @param vcpu Pointer to vCPU that initiates the hypercall 269 * @param target_vm Pointer to target VM data structure 270 * @param param1 not used 271 * @param param2 guest physical address. This gpa points to data structure of 272 * acrn_pcidev including assign PCI device info 273 * 274 * @pre is_service_vm(vcpu->vm) 275 * @return 0 on success, non-zero on error. 276 */ 277 int32_t hcall_assign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 278 279 /** 280 * @brief Deassign one PCI dev to VM. 281 * 282 * @param vcpu Pointer to vCPU that initiates the hypercall 283 * @param target_vm Pointer to target VM data structure 284 * @param param1 not used 285 * @param param2 guest physical address. This gpa points to data structure of 286 * acrn_pcidev including deassign PCI device info 287 * 288 * @pre is_service_vm(vcpu->vm) 289 * @return 0 on success, non-zero on error. 290 */ 291 int32_t hcall_deassign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 292 293 /** 294 * @brief Assign one MMIO dev to VM. 295 * 296 * @param vcpu Pointer to vCPU that initiates the hypercall 297 * @param target_vm Pointer to target VM data structure 298 * @param param1 not used 299 * @param param2 guest physical address. This gpa points to data structure of 300 * acrn_mmiodev including assign MMIO device info 301 * 302 * @pre is_service_vm(vcpu->vm) 303 * @return 0 on success, non-zero on error. 304 */ 305 int32_t hcall_assign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 306 307 /** 308 * @brief Deassign one MMIO dev to VM. 309 * 310 * @param vcpu Pointer to vCPU that initiates the hypercall 311 * @param target_vm Pointer to target VM data structure 312 * @param param1 not used 313 * @param param2 guest physical address. This gpa points to data structure of 314 * acrn_mmiodev including deassign MMIO device info 315 * 316 * @pre is_service_vm(vcpu->vm) 317 * @return 0 on success, non-zero on error. 318 */ 319 int32_t hcall_deassign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 320 321 /** 322 * @brief Add an emulated device in hypervisor. 323 * 324 * @param vcpu Pointer to vCPU that initiates the hypercall 325 * @param target_vm Pointer to target VM data structure 326 * @param param1 not used 327 * @param param2 guest physical address. This gpa points to data structure of 328 * acrn_vdev including information about PCI or legacy devices 329 * 330 * @pre is_service_vm(vcpu->vm) 331 * @return 0 on success, non-zero on error. 332 */ 333 int32_t hcall_add_vdev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 334 335 /** 336 * @brief Remove an emulated device in hypervisor. 337 * 338 * @param vcpu Pointer to vCPU that initiates the hypercall 339 * @param target_vm Pointer to target VM data structure 340 * @param param1 not used 341 * @param param2 guest physical address. This gpa points to data structure of 342 * acrn_vdev including information about PCI or legacy devices 343 * 344 * @pre is_service_vm(vcpu->vm) 345 * @return 0 on success, non-zero on error. 346 */ 347 int32_t hcall_remove_vdev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 348 349 /** 350 * @brief Set interrupt mapping info of ptdev. 351 * 352 * @param vcpu Pointer to vCPU that initiates the hypercall 353 * @param target_vm Pointer to target VM data structure 354 * @param param1 not used 355 * @param param2 guest physical address. This gpa points to data structure of 356 * hc_ptdev_irq including intr remapping info 357 * 358 * @pre is_service_vm(vcpu->vm) 359 * @return 0 on success, non-zero on error. 360 */ 361 int32_t hcall_set_ptdev_intr_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 362 363 /** 364 * @brief Clear interrupt mapping info of ptdev. 365 * 366 * @param vcpu Pointer to vCPU that initiates the hypercall 367 * @param target_vm Pointer to target VM data structure 368 * @param param1 not used 369 * @param param2 guest physical address. This gpa points to data structure of 370 * hc_ptdev_irq including intr remapping info 371 * 372 * @pre is_service_vm(vcpu->vm) 373 * @return 0 on success, non-zero on error. 374 */ 375 int32_t hcall_reset_ptdev_intr_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, 376 uint64_t param1, uint64_t param2); 377 378 /** 379 * @brief Get VCPU Power state. 380 * 381 * @param vcpu Pointer to vCPU that initiates the hypercall 382 * @param target_vm Pointer to target VM data structure 383 * @param param1 cmd to show get which VCPU power state data 384 * @param param2 VCPU power state data 385 * 386 * @pre is_service_vm(vcpu->vm) 387 * @return 0 on success, non-zero on error. 388 */ 389 int32_t hcall_get_cpu_pm_state(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 390 391 /** 392 * @brief Get VCPU a VM's interrupt count data. 393 * 394 * @param vcpu Pointer to vCPU that initiates the hypercall 395 * @param target_vm Pointer to target VM data structure 396 * @param param1 not used 397 * @param param2 guest physical address. This gpa points to data structure of 398 * acrn_intr_monitor 399 * 400 * @pre is_service_vm(vcpu->vm) 401 * @return 0 on success, non-zero on error. 402 */ 403 int32_t hcall_vm_intr_monitor(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 404 405 /** 406 * @defgroup trusty_hypercall Trusty Hypercalls 407 * 408 * This is a special group that includes all hypercalls 409 * related to Trusty 410 * 411 * @{ 412 */ 413 414 /** 415 * @brief Switch vCPU state between Normal/Secure World. 416 * 417 * * The hypervisor uses this hypercall to do the world switch 418 * * The hypervisor needs to: 419 * * save current world vCPU contexts, and load the next world 420 * vCPU contexts 421 * * update ``rdi``, ``rsi``, ``rdx``, ``rbx`` to next world 422 * vCPU contexts 423 * 424 * @param vcpu Pointer to VCPU data structure 425 * @param target_vm not used 426 * @param param1 not used 427 * @param param2 not used 428 * 429 * @return 0 on success, non-zero on error. 430 */ 431 432 int32_t hcall_world_switch(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 433 434 /** 435 * @brief Initialize environment for Trusty-OS on a vCPU. 436 * 437 * * It is used by the User VM OS bootloader (``User VM OS Loader``) to request ACRN 438 * to initialize Trusty 439 * * The Trusty memory region range, entry point must be specified 440 * * The hypervisor needs to save current vCPU contexts (Normal World) 441 * 442 * @param vcpu Pointer to vCPU data structure 443 * @param target_vm not used 444 * @param param1 guest physical address. This gpa points to 445 * trusty_boot_param structure 446 * @param param2 not used 447 * 448 * @return 0 on success, non-zero on error. 449 */ 450 int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 451 452 /** 453 * @brief Save/Restore Context of Secure World. 454 * 455 * @param vcpu Pointer to VCPU data structure 456 * @param target_vm not used 457 * @param param1 not used 458 * @param param2 not used 459 * 460 * @return 0 on success, non-zero on error. 461 */ 462 int32_t hcall_save_restore_sworld_ctx(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, 463 uint64_t param1, uint64_t param2); 464 465 /** 466 * @brief Handle the TEE boot done signal. 467 * 468 * @param vcpu Pointer to VCPU data structure 469 * @param target_vm not used 470 * @param param1 not used 471 * @param param2 not used 472 * 473 * @return 0 on success, non-zero on error. 474 */ 475 int32_t hcall_handle_tee_vcpu_boot_done(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, 476 uint64_t param1, uint64_t param2); 477 478 /** 479 * @brief Switch the execution environment. 480 * 481 * @param vcpu Pointer to VCPU data structure 482 * @param target_vm not used 483 * @param param1 not used 484 * @param param2 not used 485 * 486 * @return 0 on success, non-zero on error. 487 */ 488 int32_t hcall_switch_ee(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, 489 uint64_t param1, uint64_t param2); 490 491 /** 492 * @} 493 */ 494 /* End of trusty_hypercall */ 495 496 /** 497 * @brief set upcall notifier vector 498 * 499 * This is the API that helps to switch the notifer vecotr. If this API is 500 * not called, the hypervisor will use the default notifier vector(0xF7) 501 * to notify the Service VM OS kernel. 502 * 503 * @param vcpu not used 504 * @param target_vm not used 505 * @param param1 the expected notifier vector from guest 506 * @param param2 not used 507 * 508 * @pre is_service_vm(vcpu->vm) 509 * @return 0 on success, non-zero on error. 510 */ 511 int32_t hcall_set_callback_vector(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 512 513 /** 514 * @brief Setup a share buffer for a VM. 515 * 516 * @param vcpu Pointer to vCPU that initiates the hypercall 517 * @param target_vm not used 518 * @param param1 guest physical address. This gpa points to 519 * struct sbuf_setup_param 520 * @param param2 not used 521 * 522 * @pre is_service_vm(vcpu->vm) 523 * @return 0 on success, non-zero on error. 524 */ 525 int32_t hcall_setup_sbuf(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 526 527 /** 528 * @brief Assign an asyncio to a VM. 529 * 530 * @param vcpu not used 531 * @param target_vm which VM the asyncio belongs. 532 * @param param1 guest physical address. This gpa points to 533 * struct acrn_asyncio_info 534 * @param param2 not used 535 * 536 * @return 0 on success, non-zero on error. 537 */ 538 int32_t hcall_asyncio_assign(__unused struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, 539 __unused uint64_t param1, uint64_t param2); 540 /** 541 * @brief Deassign an asyncio from a VM. 542 * 543 * @param vcpu not used 544 * @param target_vm which VM the asyncio belongs. 545 * @param param1 guest physical address. This gpa points to 546 * struct acrn_asyncio_info 547 * @param param2 not used 548 * 549 * @return 0 on success, non-zero on error. 550 */ 551 int32_t hcall_asyncio_deassign(__unused struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, 552 __unused uint64_t param1, uint64_t param2); 553 554 /** 555 * @brief Setup the hypervisor NPK log. 556 * 557 * @param vcpu Pointer to vCPU that initiates the hypercall 558 * @param target_vm not used 559 * @param param1 guest physical address. This gpa points to 560 * struct hv_npk_log_param 561 * @param param2 not used 562 * 563 * @pre is_service_vm(vcpu->vm) 564 * @return 0 on success, non-zero on error. 565 */ 566 int32_t hcall_setup_hv_npk_log(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 567 568 /** 569 * @brief Get hardware related info 570 * 571 * @param vcpu Pointer to vCPU that initiates the hypercall 572 * @param target_vm not used 573 * @param param1 Guest physical address pointing to struct acrn_hw_info 574 * @param param2 not used 575 * 576 * @pre vm shall point to Service VM 577 * @pre param1 shall be a valid physical address 578 * 579 * @retval 0 on success 580 * @retval -1 in case of error 581 */ 582 int32_t hcall_get_hw_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 583 584 /** 585 * @brief Execute profiling operation 586 * 587 * @param vcpu Pointer to vCPU that initiates the hypercall 588 * @param target_vm not used 589 * @param param1 profiling command to be executed 590 * @param param2 guest physical address. This gpa points to 591 * data structure required by each command 592 * 593 * @pre is_service_vm(vcpu->vm) 594 * @return 0 on success, non-zero on error. 595 */ 596 int32_t hcall_profiling_ops(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 597 598 int32_t hcall_create_vcpu(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); 599 /** 600 * @} 601 */ 602 /* End of acrn_hypercall */ 603 604 #endif /* HYPERCALL_H*/ 605