mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 12:42:54 +00:00
HV:refine 'create_vm()' to avoid potential crash and memory leak
hypervisor will crash if user try to call hypercall HC_CREATE_VM in infinite style. actually, the number of VMs hypervisor can support depends on the bit width of 'vmid_bitmap'.should return error in case of overflow. other cleanup for this function to avoid memory leak in case of failure. Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
53a5941b99
commit
45d6f72b51
@ -99,14 +99,21 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
|||||||
if (vm->hw.vcpu_array == NULL) {
|
if (vm->hw.vcpu_array == NULL) {
|
||||||
pr_err("%s, vcpu_array allocation failed\n", __func__);
|
pr_err("%s, vcpu_array allocation failed\n", __func__);
|
||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
goto err1;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (id = 0U; id < (size_t)(sizeof(long) * 8U); id++) {
|
for (id = 0U; id < (size_t)(sizeof(vmid_bitmap) * 8U); id++) {
|
||||||
if (!bitmap_test_and_set(id, &vmid_bitmap)) {
|
if (!bitmap_test_and_set(id, &vmid_bitmap)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id >= (size_t)(sizeof(vmid_bitmap) * 8U)) {
|
||||||
|
pr_err("%s, no more VMs can be supported\n", __func__);
|
||||||
|
status = -EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
vm->attr.id = id;
|
vm->attr.id = id;
|
||||||
vm->attr.boot_idx = id;
|
vm->attr.boot_idx = id;
|
||||||
|
|
||||||
@ -120,7 +127,8 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
|||||||
if ((vm->arch_vm.nworld_eptp == NULL) ||
|
if ((vm->arch_vm.nworld_eptp == NULL) ||
|
||||||
(vm->arch_vm.m2p == NULL)) {
|
(vm->arch_vm.m2p == NULL)) {
|
||||||
pr_fatal("%s, alloc memory for EPTP failed\n", __func__);
|
pr_fatal("%s, alloc memory for EPTP failed\n", __func__);
|
||||||
return -ENOMEM;
|
status = -ENOMEM;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only for SOS: Configure VM software information */
|
/* Only for SOS: Configure VM software information */
|
||||||
@ -128,12 +136,12 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
|||||||
if (is_vm0(vm)) {
|
if (is_vm0(vm)) {
|
||||||
status = prepare_vm0_memmap_and_e820(vm);
|
status = prepare_vm0_memmap_and_e820(vm);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
goto err2;
|
goto err;
|
||||||
}
|
}
|
||||||
#ifndef CONFIG_EFI_STUB
|
#ifndef CONFIG_EFI_STUB
|
||||||
status = init_vm0_boot_info(vm);
|
status = init_vm0_boot_info(vm);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
goto err2;
|
goto err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -175,7 +183,7 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
|||||||
vm->arch_vm.virt_ioapic = vioapic_init(vm);
|
vm->arch_vm.virt_ioapic = vioapic_init(vm);
|
||||||
if (vm->arch_vm.virt_ioapic == NULL) {
|
if (vm->arch_vm.virt_ioapic == NULL) {
|
||||||
status = -ENODEV;
|
status = -ENODEV;
|
||||||
goto err3;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Populate return VM handle */
|
/* Populate return VM handle */
|
||||||
@ -184,20 +192,34 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
|||||||
|
|
||||||
status = set_vcpuid_entries(vm);
|
status = set_vcpuid_entries(vm);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
goto err4;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm->state = VM_CREATED;
|
vm->state = VM_CREATED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err4:
|
err:
|
||||||
vioapic_cleanup(vm->arch_vm.virt_ioapic);
|
if (vm->arch_vm.virt_ioapic != NULL) {
|
||||||
err3:
|
vioapic_cleanup(vm->arch_vm.virt_ioapic);
|
||||||
vpic_cleanup(vm);
|
}
|
||||||
err2:
|
|
||||||
free(vm->hw.vcpu_array);
|
if (vm->vpic != NULL) {
|
||||||
err1:
|
vpic_cleanup(vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm->arch_vm.m2p != NULL) {
|
||||||
|
free(vm->arch_vm.m2p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm->arch_vm.nworld_eptp != NULL) {
|
||||||
|
free(vm->arch_vm.nworld_eptp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm->hw.vcpu_array != NULL) {
|
||||||
|
free(vm->hw.vcpu_array);
|
||||||
|
}
|
||||||
|
|
||||||
free(vm);
|
free(vm);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user