acrn-hypervisor/hypervisor/arch/x86/guest/vmcall.c
Yang, Yu-chu 6f1c5fa007 HV: Logical conjunction needs brackets under /arch/x86/guest
The bracket is required when the level of precedence of
the operators is less than 13. Add the bracket to logical
conjunctions. The commit applys the rule to the files under
hypervisor/arch/x86/guest/*

Signed-off-by: Yang, Yu-chu <yu-chu.yang@intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
2018-08-14 09:53:32 +08:00

191 lines
4.2 KiB
C

/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <hypervisor.h>
#include <hypercall.h>
/*
* Pass return value to SOS by register rax.
* This function should always return 0 since we shouldn't
* deal with hypercall error in hypervisor.
*/
int vmcall_vmexit_handler(struct vcpu *vcpu)
{
int32_t ret = -EACCES;
struct vm *vm = vcpu->vm;
/* hypercall ID from guest*/
uint64_t hypcall_id = vcpu_get_gpreg(vcpu, CPU_REG_R8);
/* hypercall param1 from guest*/
uint64_t param1 = vcpu_get_gpreg(vcpu, CPU_REG_RDI);
/* hypercall param2 from guest*/
uint64_t param2 = vcpu_get_gpreg(vcpu, CPU_REG_RSI);
if (!is_hypercall_from_ring0()) {
pr_err("hypercall is only allowed from RING-0!\n");
goto out;
}
if (!is_vm0(vm) && (hypcall_id != HC_WORLD_SWITCH) &&
(hypcall_id != HC_INITIALIZE_TRUSTY) &&
(hypcall_id != HC_SAVE_RESTORE_SWORLD_CTX)) {
pr_err("hypercall %d is only allowed from VM0!\n", hypcall_id);
goto out;
}
/* Dispatch the hypercall handler */
switch (hypcall_id) {
case HC_SOS_OFFLINE_CPU:
ret = hcall_sos_offline_cpu(vm, param1);
break;
case HC_GET_API_VERSION:
#ifdef CONFIG_VM0_DESC
/* vm0 will call HC_GET_API_VERSION as first hypercall, fixup
* vm0 vcpu here.
*/
vm_fixup(vm);
#endif
ret = hcall_get_api_version(vm, param1);
break;
case HC_CREATE_VM:
ret = hcall_create_vm(vm, param1);
break;
case HC_DESTROY_VM:
/* param1: vmid */
ret = hcall_destroy_vm((uint16_t)param1);
break;
case HC_START_VM:
/* param1: vmid */
ret = hcall_start_vm((uint16_t)param1);
break;
case HC_RESET_VM:
/* param1: vmid */
ret = hcall_reset_vm((uint16_t)param1);
break;
case HC_PAUSE_VM:
/* param1: vmid */
ret = hcall_pause_vm((uint16_t)param1);
break;
case HC_CREATE_VCPU:
/* param1: vmid */
ret = hcall_create_vcpu(vm, (uint16_t)param1, param2);
break;
case HC_ASSERT_IRQLINE:
/* param1: vmid */
ret = hcall_assert_irqline(vm, (uint16_t)param1, param2);
break;
case HC_DEASSERT_IRQLINE:
/* param1: vmid */
ret = hcall_deassert_irqline(vm, (uint16_t)param1, param2);
break;
case HC_PULSE_IRQLINE:
/* param1: vmid */
ret = hcall_pulse_irqline(vm, (uint16_t)param1, param2);
break;
case HC_INJECT_MSI:
/* param1: vmid */
ret = hcall_inject_msi(vm, (uint16_t)param1, param2);
break;
case HC_SET_IOREQ_BUFFER:
/* param1: vmid */
ret = hcall_set_ioreq_buffer(vm, (uint16_t)param1, param2);
break;
case HC_NOTIFY_REQUEST_FINISH:
/* param1: vmid
* param2: vcpu_id */
ret = hcall_notify_ioreq_finish((uint16_t)param1,
(uint16_t)param2);
break;
case HC_VM_SET_MEMORY_REGION:
/* param1: vmid */
ret = hcall_set_vm_memory_region(vm, (uint16_t)param1, param2);
break;
case HC_VM_SET_MEMORY_REGIONS:
ret = hcall_set_vm_memory_regions(vm, param1);
break;
case HC_VM_WRITE_PROTECT_PAGE:
ret = hcall_write_protect_page(vm, (uint16_t)param1, param2);
break;
case HC_VM_PCI_MSIX_REMAP:
/* param1: vmid */
ret = hcall_remap_pci_msix(vm, (uint16_t)param1, param2);
break;
case HC_VM_GPA2HPA:
/* param1: vmid */
ret = hcall_gpa_to_hpa(vm, (uint16_t)param1, param2);
break;
case HC_ASSIGN_PTDEV:
/* param1: vmid */
ret = hcall_assign_ptdev(vm, (uint16_t)param1, param2);
break;
case HC_DEASSIGN_PTDEV:
/* param1: vmid */
ret = hcall_deassign_ptdev(vm, (uint16_t)param1, param2);
break;
case HC_SET_PTDEV_INTR_INFO:
/* param1: vmid */
ret = hcall_set_ptdev_intr_info(vm, (uint16_t)param1, param2);
break;
case HC_RESET_PTDEV_INTR_INFO:
/* param1: vmid */
ret = hcall_reset_ptdev_intr_info(vm, (uint16_t)param1, param2);
break;
case HC_SETUP_SBUF:
ret = hcall_setup_sbuf(vm, param1);
break;
case HC_WORLD_SWITCH:
ret = hcall_world_switch(vcpu);
break;
case HC_INITIALIZE_TRUSTY:
ret = hcall_initialize_trusty(vcpu, param1);
break;
case HC_PM_GET_CPU_STATE:
ret = hcall_get_cpu_pm_state(vm, param1, param2);
break;
case HC_SAVE_RESTORE_SWORLD_CTX:
ret = hcall_save_restore_sworld_ctx(vcpu);
break;
default:
pr_err("op %d: Invalid hypercall\n", hypcall_id);
ret = -EPERM;
break;
}
out:
vcpu_set_gpreg(vcpu, CPU_REG_RAX, (uint64_t)ret);
TRACE_2L(TRACE_VMEXIT_VMCALL, vm->vm_id, hypcall_id);
return 0;
}