mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-11 13:03:15 +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:
parent
cb10dc7e73
commit
445999af5d
@ -7,7 +7,6 @@
|
|||||||
#include <vm_config.h>
|
#include <vm_config.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <acrn_common.h>
|
#include <acrn_common.h>
|
||||||
#include <page.h>
|
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
#include <cat.h>
|
#include <cat.h>
|
||||||
|
|
||||||
@ -20,6 +19,50 @@ struct acrn_vm_config *get_vm_config(uint16_t vm_id)
|
|||||||
return &vm_configs[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
|
* @pre vm_config != NULL
|
||||||
*/
|
*/
|
||||||
@ -62,7 +105,7 @@ bool sanitize_vm_config(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NORMAL_VM:
|
case NORMAL_VM:
|
||||||
ret = false;
|
/* Nothing to do here for a NORMAL_VM, break directly. */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Nothing to do for a UNDEFINED_VM, break directly. */
|
/* 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) {
|
if (!ret) {
|
||||||
break;
|
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;
|
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;
|
uint16_t vm_id = 0U;
|
||||||
struct acrn_vm_config *vm_config;
|
|
||||||
|
|
||||||
for (id = 0U; id < CONFIG_MAX_VM_NUM; id++) {
|
while (!vm_has_matched_uuid(vm_id, uuid)) {
|
||||||
vm_config = get_vm_config(id);
|
vm_id++;
|
||||||
if (vm_config->type == UNDEFINED_VM) {
|
if (vm_id == CONFIG_MAX_VM_NUM) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (vm_config->type == UNDEFINED_VM) ? id : INVALID_VM_ID;
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_valid_vm(const struct acrn_vm *vm)
|
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);
|
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)) {
|
if (is_sos_vm(vm)) {
|
||||||
/* Only for SOS_VM */
|
/* Only for SOS_VM */
|
||||||
create_sos_vm_e820(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);
|
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) {
|
if (vm_config->type == PRE_LAUNCHED_VM) {
|
||||||
create_prelaunched_vm_e820(vm);
|
create_prelaunched_vm_e820(vm);
|
||||||
prepare_prelaunched_vm_memmap(vm, vm_config);
|
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) {
|
if (vm->arch_vm.nworld_eptp != NULL) {
|
||||||
(void)memset(vm->arch_vm.nworld_eptp, 0U, PAGE_SIZE);
|
(void)memset(vm->arch_vm.nworld_eptp, 0U, PAGE_SIZE);
|
||||||
}
|
}
|
||||||
free_vm_id(vm);
|
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -506,9 +494,6 @@ int32_t shutdown_vm(struct acrn_vm *vm)
|
|||||||
/* Free EPT allocated resources assigned to VM */
|
/* Free EPT allocated resources assigned to VM */
|
||||||
destroy_ept(vm);
|
destroy_ept(vm);
|
||||||
|
|
||||||
/* Free vm id */
|
|
||||||
free_vm_id(vm);
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -126,15 +126,10 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param)
|
|||||||
|
|
||||||
(void)memset((void *)&cv, 0U, sizeof(cv));
|
(void)memset((void *)&cv, 0U, sizeof(cv));
|
||||||
if (copy_from_gpa(vm, &cv, param, sizeof(cv)) == 0) {
|
if (copy_from_gpa(vm, &cv, param, sizeof(cv)) == 0) {
|
||||||
/* check whether there is a free vm id for use */
|
vm_id = get_vmid_by_uuid(&cv.uuid[0]);
|
||||||
/* TODO: pass vm id from DM to make vm_id static */
|
|
||||||
vm_id = find_free_vm_id();
|
|
||||||
if (vm_id < CONFIG_MAX_VM_NUM) {
|
if (vm_id < CONFIG_MAX_VM_NUM) {
|
||||||
vm_config = get_vm_config(vm_id);
|
vm_config = get_vm_config(vm_id);
|
||||||
/* TODO: set by DM */
|
|
||||||
vm_config->type = NORMAL_VM;
|
|
||||||
vm_config->guest_flags |= cv.vm_flag;
|
vm_config->guest_flags |= cv.vm_flag;
|
||||||
(void)memcpy_s(&vm_config->uuid[0], 16U, &cv.uuid[0], 16U);
|
|
||||||
|
|
||||||
/* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */
|
/* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */
|
||||||
if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U)
|
if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U)
|
||||||
|
@ -213,7 +213,7 @@ void launch_vms(uint16_t pcpu_id);
|
|||||||
bool is_valid_vm(const struct acrn_vm *vm);
|
bool is_valid_vm(const struct acrn_vm *vm);
|
||||||
bool is_sos_vm(const struct acrn_vm *vm);
|
bool is_sos_vm(const struct acrn_vm *vm);
|
||||||
bool is_prelaunched_vm(const struct acrn_vm *vm);
|
bool is_prelaunched_vm(const struct acrn_vm *vm);
|
||||||
uint16_t find_free_vm_id(void);
|
uint16_t get_vmid_by_uuid(const uint8_t *uuid);
|
||||||
struct acrn_vm *get_vm_from_vmid(uint16_t vm_id);
|
struct acrn_vm *get_vm_from_vmid(uint16_t vm_id);
|
||||||
struct acrn_vm *get_sos_vm(void);
|
struct acrn_vm *get_sos_vm(void);
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ struct acrn_vm_pci_ptdev_config {
|
|||||||
struct acrn_vm_config {
|
struct acrn_vm_config {
|
||||||
enum acrn_vm_type type; /* specify the type of VM */
|
enum acrn_vm_type type; /* specify the type of VM */
|
||||||
char name[MAX_VM_OS_NAME_LEN]; /* VM name identifier, useful for debug. */
|
char name[MAX_VM_OS_NAME_LEN]; /* VM name identifier, useful for debug. */
|
||||||
uint8_t uuid[16]; /* UUID of the VM */
|
const uint8_t uuid[16]; /* UUID of the VM */
|
||||||
uint64_t pcpu_bitmap; /* from pcpu bitmap, we could know VM core number */
|
uint64_t pcpu_bitmap; /* from pcpu bitmap, we could know VM core number */
|
||||||
uint64_t guest_flags; /* VM flags that we want to configure for guest
|
uint64_t guest_flags; /* VM flags that we want to configure for guest
|
||||||
* Now we have two flags:
|
* Now we have two flags:
|
||||||
@ -63,6 +63,7 @@ struct acrn_vm_config {
|
|||||||
} __aligned(8);
|
} __aligned(8);
|
||||||
|
|
||||||
struct acrn_vm_config *get_vm_config(uint16_t vm_id);
|
struct acrn_vm_config *get_vm_config(uint16_t vm_id);
|
||||||
|
bool vm_has_matched_uuid(uint16_t vmid, const uint8_t *uuid);
|
||||||
bool sanitize_vm_config(void);
|
bool sanitize_vm_config(void);
|
||||||
|
|
||||||
extern struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM];
|
extern struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM];
|
||||||
|
@ -15,6 +15,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
{ /* VM0 */
|
{ /* VM0 */
|
||||||
.type = PRE_LAUNCHED_VM,
|
.type = PRE_LAUNCHED_VM,
|
||||||
.name = "ACRN PRE-LAUNCHED VM0",
|
.name = "ACRN PRE-LAUNCHED VM0",
|
||||||
|
.uuid = {0x26U, 0xc5U, 0xe0U, 0xd8U, 0x8fU, 0x8aU, 0x47U, 0xd8U, \
|
||||||
|
0x81U, 0x09U, 0xf2U, 0x01U, 0xebU, 0xd6U, 0x1aU, 0x5eU},
|
||||||
|
/* 26c5e0d8-8f8a-47d8-8109-f201ebd61a5e */
|
||||||
.pcpu_bitmap = VM0_CONFIG_PCPU_BITMAP,
|
.pcpu_bitmap = VM0_CONFIG_PCPU_BITMAP,
|
||||||
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
|
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
|
||||||
.clos = 0U,
|
.clos = 0U,
|
||||||
@ -38,6 +41,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
{ /* VM1 */
|
{ /* VM1 */
|
||||||
.type = PRE_LAUNCHED_VM,
|
.type = PRE_LAUNCHED_VM,
|
||||||
.name = "ACRN PRE-LAUNCHED VM1",
|
.name = "ACRN PRE-LAUNCHED VM1",
|
||||||
|
.uuid = {0xddU, 0x87U, 0xceU, 0x08U, 0x66U, 0xf9U, 0x47U, 0x3dU, \
|
||||||
|
0xbcU, 0x58U, 0x76U, 0x05U, 0x83U, 0x7fU, 0x93U, 0x5eU},
|
||||||
|
/* dd87ce08-66f9-473d-bc58-7605837f935e */
|
||||||
.pcpu_bitmap = VM1_CONFIG_PCPU_BITMAP,
|
.pcpu_bitmap = VM1_CONFIG_PCPU_BITMAP,
|
||||||
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
|
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
|
||||||
.clos = 0U,
|
.clos = 0U,
|
||||||
|
@ -12,6 +12,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
{
|
{
|
||||||
.type = SOS_VM,
|
.type = SOS_VM,
|
||||||
.name = "ACRN SOS VM",
|
.name = "ACRN SOS VM",
|
||||||
|
.uuid = {0xdbU, 0xbbU, 0xd4U, 0x34U, 0x7aU, 0x57U, 0x42U, 0x16U, \
|
||||||
|
0xa1U, 0x2cU, 0x22U, 0x01U, 0xf1U, 0xabU, 0x02U, 0x40U},
|
||||||
|
/* dbbbd434-7a57-4216-a12c-2201f1ab0240 */
|
||||||
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
|
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
|
||||||
.clos = 0U,
|
.clos = 0U,
|
||||||
.memory = {
|
.memory = {
|
||||||
@ -22,4 +25,10 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
.name = "ACRN Service OS",
|
.name = "ACRN Service OS",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.type = NORMAL_VM,
|
||||||
|
.uuid = {0xd2U, 0x79U, 0x54U, 0x38U, 0x25U, 0xd6U, 0x11U, 0xe8U, \
|
||||||
|
0x86U, 0x4eU, 0xcbU, 0x7aU, 0x18U, 0xb3U, 0x46U, 0x43U},
|
||||||
|
/* d2795438-25d6-11e8-864e-cb7a18b34643 */
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user