HV: make vm id statically by uuid

Currently VM id of NORMAL_VM is allocated dymatically, we need to make
VM id statically for FuSa compliance.

This patch will pre-configure UUID for all VMs, then NORMAL_VM could
get its VM id/configuration from vm_configs array by indexing the UUID.

If UUID collisions is found in vm configs array, HV will refuse to
load the VM;

Tracked-On: #2291

Signed-off-by: Victor Sun <victor.sun@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Victor Sun
2019-04-09 20:39:49 +08:00
committed by ACRN System Integration
parent cb10dc7e73
commit 445999af5d
7 changed files with 77 additions and 34 deletions

View File

@@ -7,7 +7,6 @@
#include <vm_config.h>
#include <errno.h>
#include <acrn_common.h>
#include <page.h>
#include <logmsg.h>
#include <cat.h>
@@ -20,6 +19,50 @@ struct acrn_vm_config *get_vm_config(uint16_t vm_id)
return &vm_configs[vm_id];
}
static inline bool uuid_is_equal(const uint8_t *uuid1, const uint8_t *uuid2)
{
uint64_t uuid1_h = *(uint64_t *)uuid1;
uint64_t uuid1_l = *(uint64_t *)(uuid1 + 8);
uint64_t uuid2_h = *(uint64_t *)uuid2;
uint64_t uuid2_l = *(uint64_t *)(uuid2 + 8);
return ((uuid1_h == uuid2_h) && (uuid1_l == uuid2_l));
}
/**
* return true if the input uuid is configured in VM
*
* @pre vmid < CONFIG_MAX_VM_NUM
*/
bool vm_has_matched_uuid(uint16_t vmid, const uint8_t *uuid)
{
struct acrn_vm_config *vm_config = get_vm_config(vmid);
return (uuid_is_equal(&vm_config->uuid[0], uuid));
}
/**
* return true if no UUID collision is found in vm configs array start from vm_configs[vm_id]
*
* @pre vm_id < CONFIG_MAX_VM_NUM
*/
static bool check_vm_uuid_collision(uint16_t vm_id)
{
uint16_t i;
bool ret = true;
struct acrn_vm_config *start_config = get_vm_config(vm_id);
struct acrn_vm_config *following_config;
for (i = vm_id + 1U; i < CONFIG_MAX_VM_NUM; i++) {
following_config = get_vm_config(i);
if (uuid_is_equal(&start_config->uuid[0], &following_config->uuid[0])) {
ret = false;
break;
}
}
return ret;
}
/**
* @pre vm_config != NULL
*/
@@ -62,7 +105,7 @@ bool sanitize_vm_config(void)
}
break;
case NORMAL_VM:
ret = false;
/* Nothing to do here for a NORMAL_VM, break directly. */
break;
default:
/* Nothing to do for a UNDEFINED_VM, break directly. */
@@ -78,6 +121,10 @@ bool sanitize_vm_config(void)
}
}
if (ret) {
/* make sure no identical UUID in following VM configurations */
ret = check_vm_uuid_collision(vm_id);
}
if (!ret) {
break;
}

View File

@@ -34,28 +34,17 @@ static struct acrn_vm vm_array[CONFIG_MAX_VM_NUM] __aligned(PAGE_SIZE);
static struct acrn_vm *sos_vm_ptr = NULL;
uint16_t find_free_vm_id(void)
uint16_t get_vmid_by_uuid(const uint8_t *uuid)
{
uint16_t id;
struct acrn_vm_config *vm_config;
uint16_t vm_id = 0U;
for (id = 0U; id < CONFIG_MAX_VM_NUM; id++) {
vm_config = get_vm_config(id);
if (vm_config->type == UNDEFINED_VM) {
while (!vm_has_matched_uuid(vm_id, uuid)) {
vm_id++;
if (vm_id == CONFIG_MAX_VM_NUM) {
break;
}
}
return (vm_config->type == UNDEFINED_VM) ? id : INVALID_VM_ID;
}
/**
* @pre vm != NULL && vm->vmid < CONFIG_MAX_VM_NUM
*/
static inline void free_vm_id(const struct acrn_vm *vm)
{
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
vm_config->type = UNDEFINED_VM;
return vm_id;
}
bool is_valid_vm(const struct acrn_vm *vm)
@@ -363,6 +352,9 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_
register_mmio_default_emulation_handler(vm);
}
(void)memcpy_s(&vm->uuid[0], sizeof(vm->uuid),
&vm_config->uuid[0], sizeof(vm_config->uuid));
if (is_sos_vm(vm)) {
/* Only for SOS_VM */
create_sos_vm_e820(vm);
@@ -392,9 +384,6 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_
snprintf(vm_config->name, 16, "ACRN VM_%d", vm_id);
}
(void)memcpy_s(&vm->uuid[0], sizeof(vm->uuid),
&vm_config->uuid[0], sizeof(vm_config->uuid));
if (vm_config->type == PRE_LAUNCHED_VM) {
create_prelaunched_vm_e820(vm);
prepare_prelaunched_vm_memmap(vm, vm_config);
@@ -469,7 +458,6 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_
if (vm->arch_vm.nworld_eptp != NULL) {
(void)memset(vm->arch_vm.nworld_eptp, 0U, PAGE_SIZE);
}
free_vm_id(vm);
}
return status;
}
@@ -506,9 +494,6 @@ int32_t shutdown_vm(struct acrn_vm *vm)
/* Free EPT allocated resources assigned to VM */
destroy_ept(vm);
/* Free vm id */
free_vm_id(vm);
ret = 0;
} else {
ret = -EINVAL;