diff --git a/hypervisor/arch/x86/configs/vm_config.c b/hypervisor/arch/x86/configs/vm_config.c index 3c054c3ed..864392e9c 100644 --- a/hypervisor/arch/x86/configs/vm_config.c +++ b/hypervisor/arch/x86/configs/vm_config.c @@ -14,6 +14,15 @@ static uint8_t rtvm_uuid1[16] = POST_RTVM_UUID1; static uint8_t safety_vm_uuid1[16] = SAFETY_VM_UUID1; +/* + * To be used for post-launched VMS only. + * + * acrn-dm could modify post-launched VM configuration through command line arguments. + * We make use of this additional array to make sure that the dynamic configuration + * from acrn-dm won't overwrite the static vm_configs[]. + */ +static struct acrn_vm_config vm_configs_saved[CONFIG_MAX_VM_NUM]; + /* * @pre vm_id < CONFIG_MAX_VM_NUM * @post return != NULL @@ -23,6 +32,20 @@ struct acrn_vm_config *get_vm_config(uint16_t vm_id) return &vm_configs[vm_id]; } +/* + * @pre vm_id < CONFIG_MAX_VM_NUM + */ +void save_or_restore_vm_config(uint16_t vm_id, bool save) +{ + size_t size = sizeof(struct acrn_vm_config); + + if (save) { + (void)memcpy_s((void *)&vm_configs_saved[vm_id], size, (void *)&vm_configs[vm_id], size); + } else { + (void)memcpy_s((void *)&vm_configs[vm_id], size, (void *)&vm_configs_saved[vm_id], size); + } +} + static inline bool uuid_is_equal(const uint8_t *uuid1, const uint8_t *uuid2) { uint64_t uuid1_h = *(const uint64_t *)uuid1; diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index f1113ca10..b4cb66a4a 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -585,7 +585,6 @@ int32_t shutdown_vm(struct acrn_vm *vm) uint16_t i; uint64_t mask; struct acrn_vcpu *vcpu = NULL; - struct acrn_vm_config *vm_config = NULL; int32_t ret = 0; pause_vm(vm); @@ -603,9 +602,6 @@ int32_t shutdown_vm(struct acrn_vm *vm) offline_vcpu(vcpu); } - vm_config = get_vm_config(vm->vm_id); - vm_config->guest_flags &= ~DM_OWNED_GUEST_FLAG_MASK; - if (is_sos_vm(vm)) { sbuf_reset(); } diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 845adee09..368f24497 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -161,6 +161,9 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param) vm_id = get_vmid_by_uuid(&cv.uuid[0]); if ((vm_id > vm->vm_id) && (vm_id < CONFIG_MAX_VM_NUM) && (is_poweroff_vm(get_vm_from_vmid(vm_id)))) { + + /* Save a copy of the static vm configuration */ + save_or_restore_vm_config(vm_id, true); vm_config = get_vm_config(vm_id); /* Filter out the bits should not set by DM and then assign it to guest_flags */ @@ -220,6 +223,9 @@ int32_t hcall_destroy_vm(uint16_t vmid) if (!is_poweroff_vm(target_vm) && is_postlaunched_vm(target_vm)) { /* TODO: check target_vm guest_flags */ ret = shutdown_vm(target_vm); + + /* restore with the static vm configuration */ + save_or_restore_vm_config(vmid, false); } return ret; diff --git a/hypervisor/include/arch/x86/vm_config.h b/hypervisor/include/arch/x86/vm_config.h index d140b16b2..82c0f7bab 100644 --- a/hypervisor/include/arch/x86/vm_config.h +++ b/hypervisor/include/arch/x86/vm_config.h @@ -175,6 +175,7 @@ struct acrn_vm_config { } __aligned(8); struct acrn_vm_config *get_vm_config(uint16_t vm_id); +void save_or_restore_vm_config(uint16_t vm_id, bool save); bool vm_has_matched_uuid(uint16_t vmid, const uint8_t *uuid); bool sanitize_vm_config(void);