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 <victor.sun@intel.com>
Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
Victor Sun 2019-06-10 10:50:48 +08:00 committed by ACRN System Integration
parent 3d3de6bd38
commit f83ddd393f
3 changed files with 40 additions and 24 deletions

View File

@ -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 *)&param2);
@ -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);
}

View File

@ -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 *)&regions, 0U, sizeof(regions));
if (copy_from_gpa(vm, &regions, 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);
}

View File

@ -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);