diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 90928e3e3..366ed5390 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -26,7 +26,15 @@ bool is_hypercall_from_ring0(void) } /** - *@pre Pointer vm shall point to VM0 + * @brief offline vcpu from SOS + * + * The function offline specific vcpu from SOS. + * + * @param vm Pointer to VM data structure + * @param lapicid lapic id of the vcpu which wants to offline + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_sos_offline_cpu(struct acrn_vm *vm, uint64_t lapicid) { @@ -51,7 +59,16 @@ int32_t hcall_sos_offline_cpu(struct acrn_vm *vm, uint64_t lapicid) } /** - *@pre Pointer vm shall point to VM0 + * @brief Get hypervisor api version + * + * The function only return api version information when VM is VM0. + * + * @param vm Pointer to VM data structure + * @param param guest physical memory address. The api version returned + * will be copied to this gpa + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_get_api_version(struct acrn_vm *vm, uint64_t param) { @@ -69,7 +86,18 @@ int32_t hcall_get_api_version(struct acrn_vm *vm, uint64_t param) } /** - *@pre Pointer vm shall point to VM0 + * @brief create virtual machine + * + * Create a virtual machine based on parameter, currently there is no + * limitation for calling times of this function, will add MAX_VM_NUM + * support later. + * + * @param vm Pointer to VM data structure + * @param param guest physical memory address. This gpa points to + * struct acrn_create_vm + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param) { @@ -107,6 +135,16 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param) return ret; } +/** + * @brief destroy virtual machine + * + * Destroy a virtual machine, it will pause target VM then shutdown it. + * The function will return -1 if the target VM does not exist. + * + * @param vmid ID of the VM + * + * @return 0 on success, non-zero on error. + */ int32_t hcall_destroy_vm(uint16_t vmid) { int32_t ret; @@ -120,6 +158,17 @@ int32_t hcall_destroy_vm(uint16_t vmid) return ret; } +/** + * @brief start virtual machine + * + * Start a virtual machine, it will schedule target VM's vcpu to run. + * The function will return -1 if the target VM does not exist or the + * IOReq buffer page for the VM is not ready. + * + * @param vmid ID of the VM + * + * @return 0 on success, non-zero on error. + */ int32_t hcall_start_vm(uint16_t vmid) { int32_t ret; @@ -137,6 +186,17 @@ int32_t hcall_start_vm(uint16_t vmid) return ret; } +/** + * @brief pause virtual machine + * + * Pause a virtual machine, if the VM is already paused, the function + * will return 0 directly for success. + * The function will return -1 if the target VM does not exist. + * + * @param vmid ID of the VM + * + * @return 0 on success, non-zero on error. + */ int32_t hcall_pause_vm(uint16_t vmid) { struct acrn_vm *target_vm = get_vm_from_vmid(vmid); @@ -151,7 +211,19 @@ int32_t hcall_pause_vm(uint16_t vmid) } /** - *@pre Pointer vm shall point to VM0 + * @brief create vcpu + * + * Create a vcpu based on parameter for a VM, it will allocate vcpu from + * freed physical cpus, if there is no available pcpu, the function will + * return -1. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to + * struct acrn_create_vcpu + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_create_vcpu(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -180,6 +252,18 @@ int32_t hcall_create_vcpu(struct acrn_vm *vm, uint16_t vmid, uint64_t param) return ret; } +/** + * @brief reset virtual machine + * + * Reset a virtual machine, it will make target VM rerun from + * pre-defined entry. Comparing to start vm, this function reset + * each vcpu state and do some initialization for guest. + * The function will return -1 if the target VM does not exist. + * + * @param vmid ID of the VM + * + * @return 0 on success, non-zero on error. + */ int32_t hcall_reset_vm(uint16_t vmid) { struct acrn_vm *target_vm = get_vm_from_vmid(vmid); @@ -192,7 +276,18 @@ int32_t hcall_reset_vm(uint16_t vmid) } /** - *@pre Pointer vm shall point to VM0 + * @brief set vcpu regs + * + * Set the vcpu regs. It will set the vcpu init regs from DM. Now, + * it's only applied to BSP. AP always uses fixed init regs. + * The function will return -1 if the targat VM or BSP doesn't exist. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to + * struct acrn_vcpu_regs + * + * @return 0 on success, non-zero on error. */ int32_t hcall_set_vcpu_regs(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -226,7 +321,18 @@ int32_t hcall_set_vcpu_regs(struct acrn_vm *vm, uint16_t vmid, uint64_t param) } /** - *@pre Pointer vm shall point to VM0 + * @brief set or clear IRQ line + * + * Set or clear a virtual IRQ line for a VM, which could be from ISA + * or IOAPIC, normally it triggers an edge IRQ. + * The function will return -1 if the target VM does not exist. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param ops request command for IRQ set or clear + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_set_irqline(const struct acrn_vm *vm, uint16_t vmid, const struct acrn_irqline_ops *ops) @@ -259,7 +365,17 @@ int32_t hcall_set_irqline(const struct acrn_vm *vm, uint16_t vmid, } /** - *@pre Pointer vm shall point to VM0 + * @brief inject MSI interrupt + * + * Inject a MSI interrupt for a VM. + * The function will return -1 if the target VM does not exist. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to struct acrn_msi_entry + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_inject_msi(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -282,7 +398,18 @@ int32_t hcall_inject_msi(struct acrn_vm *vm, uint16_t vmid, uint64_t param) } /** - *@pre Pointer vm shall point to VM0 + * @brief set ioreq shared buffer + * + * Set the ioreq share buffer for a VM. + * The function will return -1 if the target VM does not exist. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to + * struct acrn_set_ioreq_buffer + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_set_ioreq_buffer(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -324,6 +451,17 @@ int32_t hcall_set_ioreq_buffer(struct acrn_vm *vm, uint16_t vmid, uint64_t param return 0; } +/** + * @brief notify request done + * + * Notify the requestor VCPU for the completion of an ioreq. + * The function will return -1 if the target VM does not exist. + * + * @param vmid ID of the VM + * @param vcpu_id vcpu ID of the requestor + * + * @return 0 on success, non-zero on error. + */ int32_t hcall_notify_ioreq_finish(uint16_t vmid, uint16_t vcpu_id) { struct acrn_vcpu *vcpu; @@ -431,7 +569,15 @@ static int32_t local_set_vm_memory_region(struct acrn_vm *vm, } /** - *@pre Pointer vm shall point to VM0 + * @brief setup ept memory mapping + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to + * struct vm_set_memmap + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_set_vm_memory_region(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -459,7 +605,14 @@ int32_t hcall_set_vm_memory_region(struct acrn_vm *vm, uint16_t vmid, uint64_t p } /** - *@pre Pointer vm shall point to VM0 + * @brief setup ept memory mapping for multi regions + * + * @param vm Pointer to VM data structure + * @param param guest physical address. This gpa points to + * struct set_memmaps + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_set_vm_memory_regions(struct acrn_vm *vm, uint64_t param) { @@ -538,7 +691,15 @@ static int32_t write_protect_page(struct acrn_vm *vm,const struct wp_data *wp) } /** - *@pre Pointer vm shall point to VM0 + * @brief change guest memory page write permission + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param wp_gpa guest physical address. This gpa points to + * struct wp_data + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_write_protect_page(struct acrn_vm *vm, uint16_t vmid, uint64_t wp_gpa) { @@ -565,7 +726,17 @@ int32_t hcall_write_protect_page(struct acrn_vm *vm, uint16_t vmid, uint64_t wp_ } /** - *@pre Pointer vm shall point to VM0 + * @brief translate guest physical address to host physical address + * + * Translate guest physical address to host physical address for a VM. + * The function will return -1 if the target VM does not exist. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to struct vm_gpa2hpa + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_gpa_to_hpa(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -598,7 +769,15 @@ int32_t hcall_gpa_to_hpa(struct acrn_vm *vm, uint16_t vmid, uint64_t param) } /** - *@pre Pointer vm shall point to VM0 + * @brief Assign one passthrough dev to VM. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to + * physical BDF of the assigning ptdev + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_assign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -639,7 +818,15 @@ int32_t hcall_assign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param) } /** - *@pre Pointer vm shall point to VM0 + * @brief Deassign one passthrough dev from VM. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to + * physical BDF of the deassigning ptdev + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_deassign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -662,7 +849,15 @@ int32_t hcall_deassign_ptdev(struct acrn_vm *vm, uint16_t vmid, uint64_t param) } /** - *@pre Pointer vm shall point to VM0 + * @brief Set interrupt mapping info of ptdev. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to data structure of + * hc_ptdev_irq including intr remapping info + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_set_ptdev_intr_info(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -702,7 +897,15 @@ int32_t hcall_set_ptdev_intr_info(struct acrn_vm *vm, uint16_t vmid, uint64_t pa } /** - *@pre Pointer vm shall point to VM0 + * @brief Clear interrupt mapping info of ptdev. + * + * @param vm Pointer to VM data structure + * @param vmid ID of the VM + * @param param guest physical address. This gpa points to data structure of + * hc_ptdev_irq including intr remapping info + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_reset_ptdev_intr_info(struct acrn_vm *vm, uint16_t vmid, uint64_t param) @@ -749,7 +952,14 @@ hcall_reset_ptdev_intr_info(struct acrn_vm *vm, uint16_t vmid, uint64_t param) #ifdef HV_DEBUG /** - *@pre Pointer vm shall point to VM0 + * @brief Setup a share buffer for a VM. + * + * @param vm Pointer to VM data structure + * @param param guest physical address. This gpa points to + * struct sbuf_setup_param + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_setup_sbuf(struct acrn_vm *vm, uint64_t param) { @@ -772,16 +982,30 @@ int32_t hcall_setup_sbuf(struct acrn_vm *vm, uint64_t param) return sbuf_share_setup(ssp.pcpu_id, ssp.sbuf_id, hva); } #else +/** + * @brief Setup a share buffer for a VM. + * + * @param vm Pointer to VM data structure + * @param param guest physical address. This gpa points to + * struct sbuf_setup_param + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. + */ int32_t hcall_setup_sbuf(__unused struct acrn_vm *vm, __unused uint64_t param) -{ - return -ENODEV; -} #endif #ifdef HV_DEBUG /** - *@pre Pointer vm shall point to VM0 - */ + * @brief Setup the hypervisor NPK log. + * + * @param vm Pointer to VM data structure + * @param param guest physical address. This gpa points to + * struct hv_npk_log_param + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. + */ int32_t hcall_setup_hv_npk_log(struct acrn_vm *vm, uint64_t param) { struct hv_npk_log_param npk_param; @@ -803,6 +1027,16 @@ int32_t hcall_setup_hv_npk_log(struct acrn_vm *vm, uint64_t param) return 0; } #else +/** + * @brief Setup the hypervisor NPK log. + * + * @param vm Pointer to VM data structure + * @param param guest physical address. This gpa points to + * struct hv_npk_log_param + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. + */ int32_t hcall_setup_hv_npk_log(__unused struct acrn_vm *vm, __unused uint64_t param) { return -ENODEV; @@ -810,7 +1044,14 @@ int32_t hcall_setup_hv_npk_log(__unused struct acrn_vm *vm, __unused uint64_t pa #endif /** - *@pre Pointer vm shall point to VM0 + * @brief Get VCPU Power state. + * + * @param vm pointer to VM data structure + * @param cmd cmd to show get which VCPU power state data + * @param param VCPU power state data + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_get_cpu_pm_state(struct acrn_vm *vm, uint64_t cmd, uint64_t param) { @@ -908,7 +1149,15 @@ int32_t hcall_get_cpu_pm_state(struct acrn_vm *vm, uint64_t cmd, uint64_t param) } /** - *@pre Pointer vm shall point to VM0 + * @brief Get VCPU a VM's interrupt count data. + * + * @param vm pointer to VM data structure + * @param vmid id of the VM + * @param param guest physical address. This gpa points to data structure of + * acrn_intr_monitor + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_vm_intr_monitor(struct acrn_vm *vm, uint16_t vmid, uint64_t param) { @@ -953,7 +1202,17 @@ int32_t hcall_vm_intr_monitor(struct acrn_vm *vm, uint16_t vmid, uint64_t param) } /** - *@pre Pointer vm shall point to VM0 + * @brief set upcall notifier vector + * + * This is the API that helps to switch the notifer vecotr. If this API is + * not called, the hypervisor will use the default notifier vector(0xF7) + * to notify the SOS kernel. + * + * @param vm Pointer to VM data structure + * @param param the expected notifier vector from guest + * + * @pre Pointer vm shall point to VM0 + * @return 0 on success, non-zero on error. */ int32_t hcall_set_callback_vector(const struct acrn_vm *vm, uint64_t param) { diff --git a/hypervisor/common/trusty_hypercall.c b/hypervisor/common/trusty_hypercall.c index 4e04ae836..086c13127 100644 --- a/hypervisor/common/trusty_hypercall.c +++ b/hypervisor/common/trusty_hypercall.c @@ -9,8 +9,19 @@ #define ACRN_DBG_TRUSTY_HYCALL 6U -/* this hcall is only come from trusty enabled vcpu itself, and cannot be - * called from other vcpus +/** + * @brief Switch vCPU state between Normal/Secure World. + * + * * The hypervisor uses this hypercall to do the world switch + * * The hypervisor needs to: + * * save current world vCPU contexts, and load the next world + * vCPU contexts + * * update ``rdi``, ``rsi``, ``rdx``, ``rbx`` to next world + * vCPU contexts + * + * @param vcpu Pointer to VCPU data structure + * + * @return 0 on success, non-zero on error. */ int32_t hcall_world_switch(struct acrn_vcpu *vcpu) { @@ -39,8 +50,19 @@ int32_t hcall_world_switch(struct acrn_vcpu *vcpu) return 0; } -/* this hcall is only come from trusty enabled vcpu itself, and cannot be - * called from other vcpus +/** + * @brief Initialize environment for Trusty-OS on a vCPU. + * + * * It is used by the User OS bootloader (``UOS_Loader``) to request ACRN + * to initialize Trusty + * * The Trusty memory region range, entry point must be specified + * * The hypervisor needs to save current vCPU contexts (Normal World) + * + * @param vcpu Pointer to vCPU data structure + * @param param guest physical address. This gpa points to + * trusty_boot_param structure + * + * @return 0 on success, non-zero on error. */ int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, uint64_t param) { @@ -72,6 +94,13 @@ int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, uint64_t param) return 0; } +/** + * @brief Save/Restore Context of Secure World. + * + * @param vcpu Pointer to VCPU data structure + * + * @return 0 on success, non-zero on error. + */ int64_t hcall_save_restore_sworld_ctx(struct acrn_vcpu *vcpu) { struct acrn_vm *vm = vcpu->vm;