mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-22 09:17:58 +00:00
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:
committed by
ACRN System Integration
parent
cb10dc7e73
commit
445999af5d
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user