diff --git a/hypervisor/arch/x86/configs/vm_config.c b/hypervisor/arch/x86/configs/vm_config.c index ee0f4cf00..54be51a8a 100644 --- a/hypervisor/arch/x86/configs/vm_config.c +++ b/hypervisor/arch/x86/configs/vm_config.c @@ -6,6 +6,7 @@ #include #include +#include /* * @pre vm_id < CONFIG_MAX_VM_NUM @@ -25,13 +26,27 @@ uint8_t get_vm_severity(uint16_t vm_id) } /** - * return true if the input uuid is configured in VM + * return true if the input vm-name is configured in VM * * @pre vmid < CONFIG_MAX_VM_NUM */ -bool vm_has_matched_uuid(uint16_t vmid, const uint8_t *uuid) +bool vm_has_matched_name(uint16_t vmid, const char *name) { struct acrn_vm_config *vm_config = get_vm_config(vmid); - return (uuid_is_equal(vm_config->uuid, uuid)); + 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/trusty.c b/hypervisor/arch/x86/guest/trusty.c index daeee55e5..2db2bbf0f 100644 --- a/hypervisor/arch/x86/guest/trusty.c +++ b/hypervisor/arch/x86/guest/trusty.c @@ -277,7 +277,7 @@ static bool setup_trusty_info(struct acrn_vcpu *vcpu, uint32_t mem_size, uint64_ /* Derive dvseed from dseed for Trusty */ if (derive_virtual_seed(&key_info.dseed_list[0U], &key_info.num_seeds, NULL, 0U, - vcpu->vm->uuid, sizeof(vcpu->vm->uuid))) { + (uint8_t *)vcpu->vm->name, strnlen_s(vcpu->vm->name, MAX_VM_NAME_LEN))) { /* Derive encryption key of attestation keybox from dseed */ if (derive_attkb_enc_key(key_info.attkb_enc_key)) { /* Prepare trusty startup param */ diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index c4125b9be..2dc5c18a5 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -57,16 +57,19 @@ void *get_sworld_memory_base(void) return post_user_vm_sworld_memory; } -uint16_t get_vmid_by_uuid(const uint8_t *uuid) +uint16_t get_vmid_by_name(const char *name) { - uint16_t vm_id = 0U; + uint16_t vm_id = ACRN_INVALID_VMID; + uint16_t matched_cnt = 0; - while (!vm_has_matched_uuid(vm_id, uuid)) { - vm_id++; - if (vm_id == CONFIG_MAX_VM_NUM) { - break; + /* 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); } } + return vm_id; } @@ -544,8 +547,7 @@ int32_t create_vm(uint16_t vm_id, uint64_t pcpu_bitmap, struct acrn_vm_config *v init_ept_pgtable(&vm->arch_vm.ept_pgtable, vm->vm_id); vm->arch_vm.nworld_eptp = pgtable_create_root(&vm->arch_vm.ept_pgtable); - (void)memcpy_s(&vm->uuid[0], sizeof(vm->uuid), - &vm_config->uuid[0], sizeof(vm_config->uuid)); + (void)memcpy_s(&vm->name[0], MAX_VM_NAME_LEN, &vm_config->name[0], MAX_VM_NAME_LEN); if (is_service_vm(vm)) { /* Only for Service VM */ @@ -790,6 +792,9 @@ 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_ready_for_system_shutdown()) { /* If no any guest running, shutdown system */ @@ -930,8 +935,14 @@ 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) { + 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 */ - err = create_vm(vm_id, vm_config->cpu_affinity, vm_config, &vm); + if (err == 0) { + err = create_vm(vm_id, vm_config->cpu_affinity, vm_config, &vm); + } if (err == 0) { if (is_prelaunched_vm(vm)) { diff --git a/hypervisor/arch/x86/guest/vmcall.c b/hypervisor/arch/x86/guest/vmcall.c index 0cd5a3ea1..b8df281b2 100644 --- a/hypervisor/arch/x86/guest/vmcall.c +++ b/hypervisor/arch/x86/guest/vmcall.c @@ -15,6 +15,7 @@ #include #include +static spinlock_t vm_id_lock = { .head = 0U, .tail = 0U }; struct hc_dispatch { int32_t (*handler)(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2); @@ -105,6 +106,24 @@ static const struct hc_dispatch hc_dispatch_table[] = { .permission_flags = GUEST_FLAG_SECURE_WORLD_ENABLED}, }; +uint16_t allocate_dynamical_vmid(struct acrn_vm_creation *cv) +{ + uint16_t vm_id; + struct acrn_vm_config *vm_config; + + spinlock_obtain(&vm_id_lock); + vm_id = get_unused_vmid(); + 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; +} + #define GUEST_FLAGS_ALLOWING_HYPERCALLS GUEST_FLAG_SECURE_WORLD_ENABLED struct acrn_vm *parse_target_vm(struct acrn_vm *service_vm, uint64_t hcall_id, uint64_t param1, __unused uint64_t param2) @@ -118,7 +137,19 @@ struct acrn_vm *parse_target_vm(struct acrn_vm *service_vm, uint64_t hcall_id, u switch (hcall_id) { case HC_CREATE_VM: if (copy_from_gpa(service_vm, &cv, param1, sizeof(cv)) == 0) { - vm_id = get_vmid_by_uuid(&cv.uuid[0]); + vm_id = get_vmid_by_name((char *)cv.name); + /* if the vm-name is not found, it indicates that it is not in pre-defined vm_list. + * So try to allocate one free slot to start one vm based on user-requirement + */ + 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); + } } break; diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 7fa25abd3..c9b1c1a07 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -254,13 +254,11 @@ int32_t hcall_create_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint6 int32_t ret = -1; struct acrn_vm *tgt_vm = NULL; struct acrn_vm_creation cv; - struct acrn_vm_config* vm_config = NULL; + struct acrn_vm_config *vm_config = get_vm_config(vmid); if (copy_from_gpa(vm, &cv, param1, sizeof(cv)) == 0) { if (is_poweroff_vm(get_vm_from_vmid(vmid))) { - vm_config = get_vm_config(vmid); - /* Filter out the bits should not set by DM and then assign it to guest_flags */ vm_config->guest_flags |= (cv.vm_flag & DM_OWNED_GUEST_FLAG_MASK); @@ -301,6 +299,11 @@ 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)); + } + return ret; } diff --git a/hypervisor/debug/profiling.c b/hypervisor/debug/profiling.c index ff52aa0b3..9514993ce 100644 --- a/hypervisor/debug/profiling.c +++ b/hypervisor/debug/profiling.c @@ -875,8 +875,6 @@ int32_t profiling_vm_list_info(struct acrn_vm *vm, uint64_t addr) vm_idx++; vm_info_list.vm_list[vm_idx].vm_id_num = tmp_vm->vm_id; - (void)memcpy_s((void *)vm_info_list.vm_list[vm_idx].uuid, - 16U, tmp_vm->uuid, 16U); snprintf(vm_info_list.vm_list[vm_idx].vm_name, 16U, "vm_%d", tmp_vm->vm_id, 16U); vm_info_list.vm_list[vm_idx].num_vcpus = 0; diff --git a/hypervisor/debug/shell.c b/hypervisor/debug/shell.c index 863a4321c..63140100b 100644 --- a/hypervisor/debug/shell.c +++ b/hypervisor/debug/shell.c @@ -590,8 +590,8 @@ static int32_t shell_list_vm(__unused int32_t argc, __unused char **argv) uint16_t vm_id; char state[32]; - shell_puts("\r\nVM_UUID VM_ID VM_NAME VM_STATE" - "\r\n================================ ===== ================================ ========\r\n"); + shell_puts("\r\nVM_ID VM_NAME VM_STATE" + "\r\n===== ================================ ========\r\n"); for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) { vm = get_vm_from_vmid(vm_id); @@ -614,12 +614,7 @@ static int32_t shell_list_vm(__unused int32_t argc, __unused char **argv) } vm_config = get_vm_config(vm_id); if (!is_poweroff_vm(vm)) { - int8_t i; - - for (i = 0; i < 16; i++) { - snprintf(temp_str + 2 * i, 3U, "%02x", vm->uuid[i]); - } - snprintf(temp_str + 32, MAX_STR_SIZE - 32U, " %-3d %-32s %-8s\r\n", + snprintf(temp_str, MAX_STR_SIZE, " %-3d %-32s %-8s\r\n", vm_id, vm_config->name, state); /* Output information for this task */ diff --git a/hypervisor/include/arch/x86/asm/guest/vm.h b/hypervisor/include/arch/x86/asm/guest/vm.h index 023abcaca..e08a1a644 100644 --- a/hypervisor/include/arch/x86/asm/guest/vm.h +++ b/hypervisor/include/arch/x86/asm/guest/vm.h @@ -156,7 +156,7 @@ struct acrn_vm { struct vm_io_handler_desc emul_pio[EMUL_PIO_IDX_MAX]; - uint8_t uuid[16]; + char name[MAX_VM_NAME_LEN]; struct secure_world_control sworld_control; /* Secure World's snapshot @@ -241,7 +241,7 @@ bool is_paused_vm(const struct acrn_vm *vm); bool is_service_vm(const struct acrn_vm *vm); bool is_postlaunched_vm(const struct acrn_vm *vm); bool is_prelaunched_vm(const struct acrn_vm *vm); -uint16_t get_vmid_by_uuid(const uint8_t *uuid); +uint16_t get_vmid_by_name(const char *name); struct acrn_vm *get_vm_from_vmid(uint16_t vm_id); struct acrn_vm *get_service_vm(void); diff --git a/hypervisor/include/arch/x86/asm/vm_config.h b/hypervisor/include/arch/x86/asm/vm_config.h index e5dcec111..136d0a42b 100644 --- a/hypervisor/include/arch/x86/asm/vm_config.h +++ b/hypervisor/include/arch/x86/asm/vm_config.h @@ -12,13 +12,10 @@ #include #include #include -#include #include #include #include -#define CONFIG_MAX_VM_NUM (PRE_VM_NUM + SERVICE_VM_NUM + MAX_POST_VM_NUM) - #define AFFINITY_CPU(n) (1UL << (n)) #define MAX_VCPUS_PER_VM MAX_PCPU_NUM #define MAX_VUART_NUM_PER_VM 8U @@ -38,31 +35,24 @@ #define MAX_MMIO_DEV_NUM 2U #define CONFIG_SERVICE_VM .load_order = SERVICE_VM, \ - .uuid = SERVICE_VM_UUID, \ .severity = SEVERITY_SERVICE_VM #define CONFIG_SAFETY_VM(idx) .load_order = PRE_LAUNCHED_VM, \ - .uuid = SAFETY_VM_UUID##idx, \ .severity = SEVERITY_SAFETY_VM #define CONFIG_PRE_STD_VM(idx) .load_order = PRE_LAUNCHED_VM, \ - .uuid = PRE_STANDARD_VM_UUID##idx, \ .severity = SEVERITY_STANDARD_VM #define CONFIG_PRE_RT_VM(idx) .load_order = PRE_LAUNCHED_VM, \ - .uuid = PRE_RTVM_UUID##idx, \ .severity = SEVERITY_RTVM #define CONFIG_POST_STD_VM(idx) .load_order = POST_LAUNCHED_VM, \ - .uuid = POST_STANDARD_VM_UUID##idx, \ .severity = SEVERITY_STANDARD_VM #define CONFIG_POST_RT_VM(idx) .load_order = POST_LAUNCHED_VM, \ - .uuid = POST_RTVM_UUID##idx, \ .severity = SEVERITY_RTVM #define CONFIG_KATA_VM(idx) .load_order = POST_LAUNCHED_VM, \ - .uuid = KATA_VM_UUID##idx, \ .severity = SEVERITY_STANDARD_VM /* ACRN guest severity */ @@ -154,8 +144,7 @@ struct pt_intx_config { struct acrn_vm_config { enum acrn_vm_load_order load_order; /* specify the load order of VM */ - char name[MAX_VM_OS_NAME_LEN]; /* VM name identifier, useful for debug. */ - const uint8_t uuid[16]; /* UUID of the VM */ + char name[MAX_VM_NAME_LEN]; /* VM name identifier */ uint8_t reserved[2]; /* Temporarily reserve it so that don't need to update * the users of get_platform_info frequently. */ @@ -214,7 +203,8 @@ 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_uuid(uint16_t vmid, const uint8_t *uuid); +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/common/vm_uuids.h b/hypervisor/include/common/vm_uuids.h deleted file mode 100644 index 0a06e44bb..000000000 --- a/hypervisor/include/common/vm_uuids.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2020 Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef VM_UUIDS_H -#define VM_UUIDS_H - -/* dbbbd434-7a57-4216-a12c-2201f1ab0240 */ -#define SERVICE_VM_UUID {0xdbU, 0xbbU, 0xd4U, 0x34U, 0x7aU, 0x57U, 0x42U, 0x16U, \ - 0xa1U, 0x2cU, 0x22U, 0x01U, 0xf1U, 0xabU, 0x02U, 0x40U} - -/* fc836901-8685-4bc0-8b71-6e31dc36fa47 */ -#define SAFETY_VM_UUID1 {0xfcU, 0x83U, 0x69U, 0x01U, 0x86U, 0x85U, 0x4bU, 0xc0U, \ - 0x8bU, 0x71U, 0x6eU, 0x31U, 0xdcU, 0x36U, 0xfaU, 0x47U} - -/* 26c5e0d8-8f8a-47d8-8109-f201ebd61a5e */ -#define PRE_STANDARD_VM_UUID1 {0x26U, 0xc5U, 0xe0U, 0xd8U, 0x8fU, 0x8aU, 0x47U, 0xd8U, \ - 0x81U, 0x09U, 0xf2U, 0x01U, 0xebU, 0xd6U, 0x1aU, 0x5eU} - -/* dd87ce08-66f9-473d-bc58-7605837f935e */ -#define PRE_STANDARD_VM_UUID2 {0xddU, 0x87U, 0xceU, 0x08U, 0x66U, 0xf9U, 0x47U, 0x3dU, \ - 0xbcU, 0x58U, 0x76U, 0x05U, 0x83U, 0x7fU, 0x93U, 0x5eU} - -/* d2795438-25d6-11e8-864e-cb7a18b34643 */ -#define POST_STANDARD_VM_UUID1 {0xd2U, 0x79U, 0x54U, 0x38U, 0x25U, 0xd6U, 0x11U, 0xe8U, \ - 0x86U, 0x4eU, 0xcbU, 0x7aU, 0x18U, 0xb3U, 0x46U, 0x43U} - -/* 615db82a-e189-4b4f-8dbb-d321343e4ab3 */ -#define POST_STANDARD_VM_UUID2 {0x61U, 0x5dU, 0xb8U, 0x2aU, 0xe1U, 0x89U, 0x4bU, 0x4fU, \ - 0x8dU, 0xbbU, 0xd3U, 0x21U, 0x34U, 0x3eU, 0x4aU, 0xb3U} - -/* 38158821-5208-4005-b72a-8a609e4190d0 */ -#define POST_STANDARD_VM_UUID3 {0x38U, 0x15U, 0x88U, 0x21U, 0x52U, 0x08U, 0x40U, 0x05U, \ - 0xb7U, 0x2aU, 0x8aU, 0x60U, 0x9eU, 0x41U, 0x90U, 0xd0U} - -/* a6750180-f87a-48d2-91d9-4e7f62b6519e */ -#define POST_STANDARD_VM_UUID4 {0xa6U, 0x75U, 0x01U, 0x80U, 0xf8U, 0x7aU, 0x48U, 0xd2U, \ - 0x91U, 0xd9U, 0x4eU, 0x7fU, 0x62U, 0xb6U, 0x51U, 0x9eU} - -/* d1816e4a-a9bb-4cb4-a066-3f1a8a5ce73f */ -#define POST_STANDARD_VM_UUID5 {0xd1U, 0x81U, 0x6eU, 0x4aU, 0xa9U, 0xbbU, 0x4cU, 0xb4U, \ - 0xa0U, 0x66U, 0x3fU, 0x1aU, 0x8aU, 0x5cU, 0xe7U, 0x3fU} - -/* b2a92bec-ca6b-11ea-b106-3716a8ba0bb9 */ -#define PRE_RTVM_UUID1 {0xb2U, 0xa9U, 0x2bU, 0xecU, 0xcaU, 0x6bU, 0x11U, 0xeaU, \ - 0xb1U, 0x06U, 0x37U, 0x16U, 0xa8U, 0xbaU, 0x0bU, 0xb9} - -/* 495ae2e5-2603-4d64-af76-d4bc5a8ec0e5 */ -#define POST_RTVM_UUID1 {0x49U, 0x5aU, 0xe2U, 0xe5U, 0x26U, 0x03U, 0x4dU, 0x64U, \ - 0xafU, 0x76U, 0xd4U, 0xbcU, 0x5aU, 0x8eU, 0xc0U, 0xe5U} - -/* a7ada506-1ab0-4b6b-a0da-e513ca9b8c2f */ -#define KATA_VM_UUID1 {0xa7U, 0xadU, 0xa5U, 0x06U, 0x1aU, 0xb0U, 0x4bU, 0x6bU, \ - 0xa0U, 0xdaU, 0xe5U, 0x13U, 0xcaU, 0x9bU, 0x8cU, 0x2fU} - -#endif /* VM_UUIDS_H */ diff --git a/hypervisor/include/debug/profiling_internal.h b/hypervisor/include/debug/profiling_internal.h index 43d8da3f8..f1267ab5e 100644 --- a/hypervisor/include/debug/profiling_internal.h +++ b/hypervisor/include/debug/profiling_internal.h @@ -111,7 +111,6 @@ struct profiling_vcpu_pcpu_map { struct profiling_vm_info { uint16_t vm_id_num; - uint8_t uuid[16]; char vm_name[16]; uint16_t num_vcpus; struct profiling_vcpu_pcpu_map cpu_map[MAX_VCPUS_PER_VM]; diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index d00974a51..99d559249 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -58,6 +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 */ /* 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 */ @@ -67,6 +68,8 @@ #define VIRTUAL_PM1A_SLP_EN 0x2000U #define VIRTUAL_PM1A_ALWAYS_ZERO 0xc003 +#define MAX_VM_NAME_LEN (16U) + /** * @brief Hypercall * @@ -351,8 +354,8 @@ struct acrn_vm_creation { /** Reserved */ uint16_t reserved1; - /** the UUID of this VM */ - uint8_t uuid[16]; + /** the name of this VM */ + uint8_t name[MAX_VM_NAME_LEN]; /* VM flag bits from Guest OS, now used * GUEST_FLAG_SECURE_WORLD_ENABLED (1UL<<0) @@ -591,12 +594,9 @@ enum acrn_vm_load_order { MAX_LOAD_ORDER }; -#define MAX_VM_OS_NAME_LEN 32U - struct acrn_vm_config_header { enum acrn_vm_load_order load_order; - char name[MAX_VM_OS_NAME_LEN]; - const uint8_t uuid[16]; + char name[MAX_VM_NAME_LEN]; uint8_t reserved[2]; uint8_t severity; uint64_t cpu_affinity;