diff --git a/hypervisor/arch/x86/configs/vm_config.c b/hypervisor/arch/x86/configs/vm_config.c index 54be51a8a..be947309c 100644 --- a/hypervisor/arch/x86/configs/vm_config.c +++ b/hypervisor/arch/x86/configs/vm_config.c @@ -36,17 +36,3 @@ bool vm_has_matched_name(uint16_t vmid, const char *name) return (strncmp(vm_config->name, name, MAX_VM_NAME_LEN) == 0); } - -uint16_t get_unused_vmid(void) -{ - uint16_t vm_id; - struct acrn_vm_config *vm_config; - - for (vm_id = 0; vm_id < CONFIG_MAX_VM_NUM; vm_id++) { - vm_config = get_vm_config(vm_id); - if (vm_config->name[0] == '\0') { - break; - } - } - return (vm_id < CONFIG_MAX_VM_NUM) ? (vm_id) : (ACRN_INVALID_VMID); -} diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 2dc5c18a5..ff2c4ed73 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -57,20 +57,30 @@ void *get_sworld_memory_base(void) return post_user_vm_sworld_memory; } -uint16_t get_vmid_by_name(const char *name) +uint16_t get_unused_vmid(void) { - uint16_t vm_id = ACRN_INVALID_VMID; - uint16_t matched_cnt = 0; + uint16_t vm_id; + struct acrn_vm_config *vm_config; - /* check if there are duplicate VM names in vm configurations */ - for (uint16_t idx = 0U; idx < CONFIG_MAX_VM_NUM; idx++) { - if ((*name != '\0') && vm_has_matched_name(idx, name)) { - matched_cnt++; - vm_id = (matched_cnt > 1) ? (ACRN_INVALID_VMID) : (idx); + for (vm_id = 0; vm_id < CONFIG_MAX_VM_NUM; vm_id++) { + vm_config = get_vm_config(vm_id); + if ((vm_config->name[0] == '\0') && ((vm_config->guest_flags & GUEST_FLAG_STATIC_VM) == 0U)) { + break; } } + return (vm_id < CONFIG_MAX_VM_NUM) ? (vm_id) : (ACRN_INVALID_VMID); +} - return vm_id; +uint16_t get_vmid_by_name(const char *name) +{ + uint16_t vm_id; + + for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) { + if ((*name != '\0') && vm_has_matched_name(vm_id, name)) { + break; + } + } + return (vm_id < CONFIG_MAX_VM_NUM) ? (vm_id) : (ACRN_INVALID_VMID); } /** @@ -164,6 +174,16 @@ bool is_vcat_configured(const struct acrn_vm *vm) return ((vm_config->guest_flags & GUEST_FLAG_VCAT_ENABLED) != 0U); } +/** + * @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM + */ +bool is_static_configured_vm(const struct acrn_vm *vm) +{ + struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); + + return ((vm_config->guest_flags & GUEST_FLAG_STATIC_VM) != 0U); +} + /** * @brief VT-d PI posted mode can possibly be used for PTDEVs assigned * to this VM if platform supports VT-d PI AND lapic passthru is not configured @@ -792,8 +812,8 @@ int32_t shutdown_vm(struct acrn_vm *vm) /* after guest_flags not used, then clear it */ vm_config = get_vm_config(vm->vm_id); vm_config->guest_flags &= ~DM_OWNED_GUEST_FLAG_MASK; - if ((vm_config->guest_flags & GUEST_FLAG_DYN_VM_CFG) != 0UL) { - memset(vm_config, 0U, sizeof(struct acrn_vm_config)); + if (!is_static_configured_vm(vm)) { + memset(vm_config->name, 0U, MAX_VM_NAME_LEN); } if (is_ready_for_system_shutdown()) { @@ -935,12 +955,11 @@ void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config) #ifdef CONFIG_SECURITY_VM_FIXUP security_vm_fixup(vm_id); #endif - if (get_vmid_by_name(vm_config->name) == ACRN_INVALID_VMID) { + if (get_vmid_by_name(vm_config->name) != vm_id) { pr_err("Invalid VM name: %s", vm_config->name); err = -1; - } - /* Service VM and pre-launched VMs launch on all pCPUs defined in vm_config->cpu_affinity */ - if (err == 0) { + } else { + /* Service VM and pre-launched VMs launch on all pCPUs defined in vm_config->cpu_affinity */ err = create_vm(vm_id, vm_config->cpu_affinity, vm_config, &vm); } diff --git a/hypervisor/arch/x86/guest/vmcall.c b/hypervisor/arch/x86/guest/vmcall.c index b8df281b2..688c69f93 100644 --- a/hypervisor/arch/x86/guest/vmcall.c +++ b/hypervisor/arch/x86/guest/vmcall.c @@ -116,9 +116,7 @@ uint16_t allocate_dynamical_vmid(struct acrn_vm_creation *cv) if (vm_id != ACRN_INVALID_VMID) { vm_config = get_vm_config(vm_id); memcpy_s(vm_config->name, MAX_VM_NAME_LEN, cv->name, MAX_VM_NAME_LEN); - vm_config->guest_flags = (cv->vm_flag | GUEST_FLAG_DYN_VM_CFG); vm_config->cpu_affinity = cv->cpu_affinity; - vm_config->load_order = POST_LAUNCHED_VM; } spinlock_release(&vm_id_lock); return vm_id; @@ -143,12 +141,12 @@ struct acrn_vm *parse_target_vm(struct acrn_vm *service_vm, uint64_t hcall_id, u */ if (vm_id == ACRN_INVALID_VMID) { vm_id = allocate_dynamical_vmid(&cv); - } - /* it doesn't find the available vm_slot for the given vm_name. - * Maybe the CONFIG_MAX_VM_NUM is too small to start the VM. - */ - if (vm_id == ACRN_INVALID_VMID) { - pr_err("The VM name provided (%s) is invalid, cannot create VM", cv.name); + /* it doesn't find the available vm_slot for the given vm_name. + * Maybe the CONFIG_MAX_VM_NUM is too small to start the VM. + */ + if (vm_id == ACRN_INVALID_VMID) { + pr_err("The VM name provided (%s) is invalid, cannot create VM", cv.name); + } } } break; diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 10b157ca6..6fc18a671 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -259,6 +259,7 @@ int32_t hcall_create_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint6 if (is_poweroff_vm(get_vm_from_vmid(vmid))) { /* Filter out the bits should not set by DM and then assign it to guest_flags */ + vm_config->guest_flags &= ~DM_OWNED_GUEST_FLAG_MASK; vm_config->guest_flags |= (cv.vm_flag & DM_OWNED_GUEST_FLAG_MASK); /* post-launched VM is allowed to choose pCPUs from vm_config->cpu_affinity only */ @@ -298,9 +299,8 @@ int32_t hcall_create_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint6 } - if (((ret != 0) || (cv.vmid == ACRN_INVALID_VMID)) - && (vm_config->guest_flags & GUEST_FLAG_DYN_VM_CFG) != 0UL) { - memset(vm_config, 0U, sizeof(struct acrn_vm_config)); + if (((ret != 0) || (cv.vmid == ACRN_INVALID_VMID)) && (!is_static_configured_vm(target_vm))) { + memset(vm_config->name, 0U, MAX_VM_NAME_LEN); } return ret; diff --git a/hypervisor/include/arch/x86/asm/guest/vm.h b/hypervisor/include/arch/x86/asm/guest/vm.h index e08a1a644..c3d9d8d2d 100644 --- a/hypervisor/include/arch/x86/asm/guest/vm.h +++ b/hypervisor/include/arch/x86/asm/guest/vm.h @@ -257,6 +257,8 @@ bool is_lapic_pt_configured(const struct acrn_vm *vm); bool is_rt_vm(const struct acrn_vm *vm); bool is_nvmx_configured(const struct acrn_vm *vm); bool is_vcat_configured(const struct acrn_vm *vm); +bool is_static_configured_vm(const struct acrn_vm *vm); +uint16_t get_unused_vmid(void); bool is_pi_capable(const struct acrn_vm *vm); bool has_rt_vm(void); struct acrn_vm *get_highest_severity_vm(bool runtime); diff --git a/hypervisor/include/arch/x86/asm/vm_config.h b/hypervisor/include/arch/x86/asm/vm_config.h index 640125557..edd1a1019 100644 --- a/hypervisor/include/arch/x86/asm/vm_config.h +++ b/hypervisor/include/arch/x86/asm/vm_config.h @@ -37,19 +37,19 @@ #define CONFIG_SERVICE_VM .load_order = SERVICE_VM, \ .severity = SEVERITY_SERVICE_VM -#define CONFIG_SAFETY_VM(idx) .load_order = PRE_LAUNCHED_VM, \ +#define CONFIG_SAFETY_VM .load_order = PRE_LAUNCHED_VM, \ .severity = SEVERITY_SAFETY_VM -#define CONFIG_PRE_STD_VM(idx) .load_order = PRE_LAUNCHED_VM, \ +#define CONFIG_PRE_STD_VM .load_order = PRE_LAUNCHED_VM, \ .severity = SEVERITY_STANDARD_VM -#define CONFIG_PRE_RT_VM(idx) .load_order = PRE_LAUNCHED_VM, \ +#define CONFIG_PRE_RT_VM .load_order = PRE_LAUNCHED_VM, \ .severity = SEVERITY_RTVM -#define CONFIG_POST_STD_VM(idx) .load_order = POST_LAUNCHED_VM, \ +#define CONFIG_POST_STD_VM .load_order = POST_LAUNCHED_VM, \ .severity = SEVERITY_STANDARD_VM -#define CONFIG_POST_RT_VM(idx) .load_order = POST_LAUNCHED_VM, \ +#define CONFIG_POST_RT_VM .load_order = POST_LAUNCHED_VM, \ .severity = SEVERITY_RTVM /* ACRN guest severity */ @@ -201,7 +201,6 @@ struct acrn_vm_config { struct acrn_vm_config *get_vm_config(uint16_t vm_id); uint8_t get_vm_severity(uint16_t vm_id); bool vm_has_matched_name(uint16_t vmid, const char *name); -uint16_t get_unused_vmid(void); extern struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM]; diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index 99d559249..c1bb8a982 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -58,7 +58,7 @@ #define GUEST_FLAG_NVMX_ENABLED (1UL << 5U) /* Whether this VM supports nested virtualization */ #define GUEST_FLAG_SECURITY_VM (1UL << 6U) /* Whether this VM needs to do security-vm related fixup (TPM2 and SMBIOS pt) */ #define GUEST_FLAG_VCAT_ENABLED (1UL << 7U) /* Whether this VM supports vCAT */ -#define GUEST_FLAG_DYN_VM_CFG (1UL << 8U) /* Whether this VM uses dynamic VM configuration */ +#define GUEST_FLAG_STATIC_VM (1UL << 8U) /* Whether this VM uses static VM configuration */ /* TODO: We may need to get this addr from guest ACPI instead of hardcode here */ #define VIRTUAL_SLEEP_CTL_ADDR 0x400U /* Pre-launched VM uses ACPI reduced HW mode and sleep control register */