mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-23 17:58:30 +00:00
hv: remove UUID
With current arch design the UUID is used to identify ACRN VMs, all VM configurations must be deployed with given UUIDs at build time. For post-launched VMs, end user must use UUID as acrn-dm parameter to launch specified user VM. This is not friendly for end users that they have to look up the pre-configured UUID before launching VM, and then can only launch the VM which its UUID in the pre-configured UUID list,otherwise the launch will fail.Another side, VM name is much straight forward for end user to identify VMs, whereas the VM name defined in launch script has not been passed to hypervisor VM configuration so it is not consistent with the VM name when user list VM in hypervisor shell, this would confuse user a lot. This patch will resolve these issues by removing UUID as VM identifier and use VM name instead: 1. Hypervisor will check the VM name duplication during VM creation time to make sure the VM name is unique. 2. If the VM name passed from acrn-dm matches one of pre-configured VM configurations, the corresponding VM will be launched, we call it static configured VM. If there is no matching found, hypervisor will try to allocate one unused VM configuration slot for this VM with given VM name and get it run if VM number does not reach CONFIG_MAX_VM_NUM, we will call it dynamic configured VM. 3. For dynamic configured VMs, we need a guest flag to identify them because the VM configuration need to be destroyed when it is shutdown or creation failed. v7->v8: -- rename is_static_vm_configured to is_static_configured_vm -- only set DM owned guest_flags in hcall_create_vm -- add check dynamic flag in get_unused_vmid v6->v7: -- refine get_vmid_by_name, return the first matching vm_id -- the GUEST_FLAG_STATIC_VM is added to identify the static or dynamic VM, the offline tool will set this flag for all the pre-defined VMs. -- only clear name field for dynamic VM instead of clear entire vm_config Tracked-On: #6685 Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com> Reviewed-by: Zhao Yakui <yakui.zhao@intel.com> Reviewed-by: Victor Sun<victor.sun@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
@@ -279,7 +279,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 */
|
||||
|
@@ -58,17 +58,30 @@ 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_unused_vmid(void)
|
||||
{
|
||||
uint16_t vm_id = 0U;
|
||||
uint16_t vm_id;
|
||||
struct acrn_vm_config *vm_config;
|
||||
|
||||
while (!vm_has_matched_uuid(vm_id, uuid)) {
|
||||
vm_id++;
|
||||
if (vm_id == CONFIG_MAX_VM_NUM) {
|
||||
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;
|
||||
return (vm_id < CONFIG_MAX_VM_NUM) ? (vm_id) : (ACRN_INVALID_VMID);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,6 +175,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
|
||||
@@ -546,8 +569,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 */
|
||||
@@ -792,6 +814,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 (!is_static_configured_vm(vm)) {
|
||||
memset(vm_config->name, 0U, MAX_VM_NAME_LEN);
|
||||
}
|
||||
|
||||
if (is_ready_for_system_shutdown()) {
|
||||
/* If no any guest running, shutdown system */
|
||||
@@ -932,8 +957,13 @@ void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config)
|
||||
#ifdef CONFIG_SECURITY_VM_FIXUP
|
||||
security_vm_fixup(vm_id);
|
||||
#endif
|
||||
/* 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 (get_vmid_by_name(vm_config->name) != vm_id) {
|
||||
pr_err("Invalid VM name: %s", vm_config->name);
|
||||
err = -1;
|
||||
} 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);
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
if (is_prelaunched_vm(vm)) {
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include <trace.h>
|
||||
#include <logmsg.h>
|
||||
|
||||
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,22 @@ 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->cpu_affinity = cv->cpu_affinity;
|
||||
}
|
||||
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 +135,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;
|
||||
|
||||
|
Reference in New Issue
Block a user