From f83ddd393f4eb2af2e50a0ea7cf8c3972b9aa301 Mon Sep 17 00:00:00 2001 From: Victor Sun Date: Mon, 10 Jun 2019 10:50:48 +0800 Subject: [PATCH] HV: introduce relative vm id for hcall api On SDC scenario, SOS VM id is fixed to 0 so some hypercalls from guest are using hardcoded "0" to represent SOS VM, this would bring issues for HYBRID scenario which SOS VM id is non-zero. Now introducing a new VM id concept for DM/VHM hypercall APIs, that return a relative VM id which is from SOS view when create VM for post- launched VMs. DM/VHM could always treat their own vm id is "0". When they make hypercalls, hypervisor will convert the VM id to the absolute id when dispatch the hypercalls. Tracked-On: #3214 Signed-off-by: Victor Sun Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vmcall.c | 39 +++++++++++++------------- hypervisor/common/hypercall.c | 15 ++++++---- hypervisor/include/arch/x86/guest/vm.h | 10 +++++++ 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/hypervisor/arch/x86/guest/vmcall.c b/hypervisor/arch/x86/guest/vmcall.c index 28a09ebdb..aa5906a46 100644 --- a/hypervisor/arch/x86/guest/vmcall.c +++ b/hypervisor/arch/x86/guest/vmcall.c @@ -28,8 +28,9 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) uint64_t param1 = vcpu_get_gpreg(vcpu, CPU_REG_RDI); /* hypercall param2 from guest*/ uint64_t param2 = vcpu_get_gpreg(vcpu, CPU_REG_RSI); - /* in case hypercall param1 is a vm id */ - uint16_t vm_id = (uint16_t)param1; + /* hypercall param1 is a relative vm id from SOS view */ + uint16_t relative_vm_id = (uint16_t)param1; + uint16_t vm_id = rel_vmid_2_vmid(sos_vm->vm_id, relative_vm_id); bool vmid_is_valid = (vm_id < CONFIG_MAX_VM_NUM) ? true : false; int32_t ret = -1; @@ -59,7 +60,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_DESTROY_VM: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { spinlock_obtain(&vmm_hypercall_lock); ret = hcall_destroy_vm(vm_id); @@ -68,7 +69,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_START_VM: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { spinlock_obtain(&vmm_hypercall_lock); ret = hcall_start_vm(vm_id); @@ -77,7 +78,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_RESET_VM: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { spinlock_obtain(&vmm_hypercall_lock); ret = hcall_reset_vm(vm_id); @@ -86,7 +87,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_PAUSE_VM: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { spinlock_obtain(&vmm_hypercall_lock); ret = hcall_pause_vm(vm_id); @@ -95,7 +96,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_CREATE_VCPU: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { spinlock_obtain(&vmm_hypercall_lock); ret = hcall_create_vcpu(sos_vm, vm_id, param2); @@ -104,7 +105,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_SET_VCPU_REGS: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { spinlock_obtain(&vmm_hypercall_lock); ret = hcall_set_vcpu_regs(sos_vm, vm_id, param2); @@ -113,7 +114,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_SET_IRQLINE: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_set_irqline(sos_vm, vm_id, (struct acrn_irqline_ops *)¶m2); @@ -121,14 +122,14 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_INJECT_MSI: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_inject_msi(sos_vm, vm_id, param2); } break; case HC_SET_IOREQ_BUFFER: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { spinlock_obtain(&vmm_hypercall_lock); ret = hcall_set_ioreq_buffer(sos_vm, vm_id, param2); @@ -137,7 +138,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_NOTIFY_REQUEST_FINISH: - /* param1: vmid + /* param1: relative vmid to sos, vm_id: absolute vmid * param2: vcpu_id */ if (vmid_is_valid) { ret = hcall_notify_ioreq_finish(vm_id, @@ -150,7 +151,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_VM_WRITE_PROTECT_PAGE: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_write_protect_page(sos_vm, vm_id, param2); } @@ -165,35 +166,35 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_VM_GPA2HPA: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_gpa_to_hpa(sos_vm, vm_id, param2); } break; case HC_ASSIGN_PTDEV: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_assign_ptdev(sos_vm, vm_id, param2); } break; case HC_DEASSIGN_PTDEV: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_deassign_ptdev(sos_vm, vm_id, param2); } break; case HC_SET_PTDEV_INTR_INFO: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_set_ptdev_intr_info(sos_vm, vm_id, param2); } break; case HC_RESET_PTDEV_INTR_INFO: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_reset_ptdev_intr_info(sos_vm, vm_id, param2); } @@ -204,7 +205,7 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu) break; case HC_VM_INTR_MONITOR: - /* param1: vmid */ + /* param1: relative vmid to sos, vm_id: absolute vmid */ if (vmid_is_valid) { ret = hcall_vm_intr_monitor(sos_vm, vm_id, param2); } diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index f3ce86129..43a7e6cc6 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -153,7 +153,7 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param) (void)memset((void *)&cv, 0U, sizeof(cv)); if (copy_from_gpa(vm, &cv, param, sizeof(cv)) == 0) { vm_id = get_vmid_by_uuid(&cv.uuid[0]); - if ((vm_id < CONFIG_MAX_VM_NUM) + if ((vm_id > vm->vm_id) && (vm_id < CONFIG_MAX_VM_NUM) && (is_poweroff_vm(get_vm_from_vmid(vm_id)))) { vm_config = get_vm_config(vm_id); @@ -172,7 +172,8 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param) cv.vmid = ACRN_INVALID_VMID; ret = -1; } else { - cv.vmid = target_vm->vm_id; + /* return a relative vm_id from SOS view */ + cv.vmid = vmid_2_rel_vmid(vm->vm_id, vm_id); ret = 0; } @@ -699,8 +700,11 @@ int32_t hcall_set_vm_memory_regions(struct acrn_vm *vm, uint64_t param) (void)memset((void *)®ions, 0U, sizeof(regions)); if (copy_from_gpa(vm, ®ions, param, sizeof(regions)) == 0) { - if (regions.vmid < CONFIG_MAX_VM_NUM) { - target_vm = get_vm_from_vmid(regions.vmid); + /* the vmid in regions is a relative vm id, need to convert to absolute vm id */ + uint16_t target_vmid = rel_vmid_2_vmid(vm->vm_id, regions.vmid); + + if (target_vmid < CONFIG_MAX_VM_NUM) { + target_vm = get_vm_from_vmid(target_vmid); } if ((target_vm != NULL) && !is_poweroff_vm(target_vm) && is_postlaunched_vm(target_vm)) { idx = 0U; @@ -1040,7 +1044,8 @@ int32_t hcall_get_cpu_pm_state(struct acrn_vm *vm, uint64_t cmd, uint64_t param) struct acrn_vm *target_vm = NULL; int32_t ret = -1; - target_vm_id = (uint16_t)((cmd & PMCMD_VMID_MASK) >> PMCMD_VMID_SHIFT); + /* the vmid in cmd is a relative vm id, need to convert to absolute vm id */ + target_vm_id = rel_vmid_2_vmid(vm->vm_id, (uint16_t)((cmd & PMCMD_VMID_MASK) >> PMCMD_VMID_SHIFT)); if (target_vm_id < CONFIG_MAX_VM_NUM) { target_vm = get_vm_from_vmid(target_vm_id); } diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index ff21c3c02..47a420aef 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -180,6 +180,16 @@ static inline struct acrn_vcpu *vcpu_from_pid(struct acrn_vm *vm, uint16_t pcpu_ return target_vcpu; } +/* Convert relative vm id to absolute vm id */ +static inline uint16_t rel_vmid_2_vmid(uint16_t sos_vmid, uint16_t rel_vmid) { + return (sos_vmid + rel_vmid); +} + +/* Convert absolute vm id to relative vm id */ +static inline uint16_t vmid_2_rel_vmid(uint16_t sos_vmid, uint16_t vmid) { + return (vmid - sos_vmid); +} + int32_t shutdown_vm(struct acrn_vm *vm); void pause_vm(struct acrn_vm *vm); void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec);