Skip to content

Commit 445999a

Browse files
jsun26intelacrnsi
authored andcommitted
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>
1 parent cb10dc7 commit 445999a

File tree

7 files changed

+77
-34
lines changed

7 files changed

+77
-34
lines changed

hypervisor/arch/x86/configs/vm_config.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <vm_config.h>
88
#include <errno.h>
99
#include <acrn_common.h>
10-
#include <page.h>
1110
#include <logmsg.h>
1211
#include <cat.h>
1312

@@ -20,6 +19,50 @@ struct acrn_vm_config *get_vm_config(uint16_t vm_id)
2019
return &vm_configs[vm_id];
2120
}
2221

22+
static inline bool uuid_is_equal(const uint8_t *uuid1, const uint8_t *uuid2)
23+
{
24+
uint64_t uuid1_h = *(uint64_t *)uuid1;
25+
uint64_t uuid1_l = *(uint64_t *)(uuid1 + 8);
26+
uint64_t uuid2_h = *(uint64_t *)uuid2;
27+
uint64_t uuid2_l = *(uint64_t *)(uuid2 + 8);
28+
29+
return ((uuid1_h == uuid2_h) && (uuid1_l == uuid2_l));
30+
}
31+
32+
/**
33+
* return true if the input uuid is configured in VM
34+
*
35+
* @pre vmid < CONFIG_MAX_VM_NUM
36+
*/
37+
bool vm_has_matched_uuid(uint16_t vmid, const uint8_t *uuid)
38+
{
39+
struct acrn_vm_config *vm_config = get_vm_config(vmid);
40+
41+
return (uuid_is_equal(&vm_config->uuid[0], uuid));
42+
}
43+
44+
/**
45+
* return true if no UUID collision is found in vm configs array start from vm_configs[vm_id]
46+
*
47+
* @pre vm_id < CONFIG_MAX_VM_NUM
48+
*/
49+
static bool check_vm_uuid_collision(uint16_t vm_id)
50+
{
51+
uint16_t i;
52+
bool ret = true;
53+
struct acrn_vm_config *start_config = get_vm_config(vm_id);
54+
struct acrn_vm_config *following_config;
55+
56+
for (i = vm_id + 1U; i < CONFIG_MAX_VM_NUM; i++) {
57+
following_config = get_vm_config(i);
58+
if (uuid_is_equal(&start_config->uuid[0], &following_config->uuid[0])) {
59+
ret = false;
60+
break;
61+
}
62+
}
63+
return ret;
64+
}
65+
2366
/**
2467
* @pre vm_config != NULL
2568
*/
@@ -62,7 +105,7 @@ bool sanitize_vm_config(void)
62105
}
63106
break;
64107
case NORMAL_VM:
65-
ret = false;
108+
/* Nothing to do here for a NORMAL_VM, break directly. */
66109
break;
67110
default:
68111
/* Nothing to do for a UNDEFINED_VM, break directly. */
@@ -78,6 +121,10 @@ bool sanitize_vm_config(void)
78121
}
79122
}
80123

124+
if (ret) {
125+
/* make sure no identical UUID in following VM configurations */
126+
ret = check_vm_uuid_collision(vm_id);
127+
}
81128
if (!ret) {
82129
break;
83130
}

hypervisor/arch/x86/guest/vm.c

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,17 @@ static struct acrn_vm vm_array[CONFIG_MAX_VM_NUM] __aligned(PAGE_SIZE);
3434

3535
static struct acrn_vm *sos_vm_ptr = NULL;
3636

37-
uint16_t find_free_vm_id(void)
37+
uint16_t get_vmid_by_uuid(const uint8_t *uuid)
3838
{
39-
uint16_t id;
40-
struct acrn_vm_config *vm_config;
39+
uint16_t vm_id = 0U;
4140

42-
for (id = 0U; id < CONFIG_MAX_VM_NUM; id++) {
43-
vm_config = get_vm_config(id);
44-
if (vm_config->type == UNDEFINED_VM) {
41+
while (!vm_has_matched_uuid(vm_id, uuid)) {
42+
vm_id++;
43+
if (vm_id == CONFIG_MAX_VM_NUM) {
4544
break;
4645
}
4746
}
48-
return (vm_config->type == UNDEFINED_VM) ? id : INVALID_VM_ID;
49-
}
50-
51-
/**
52-
* @pre vm != NULL && vm->vmid < CONFIG_MAX_VM_NUM
53-
*/
54-
static inline void free_vm_id(const struct acrn_vm *vm)
55-
{
56-
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
57-
58-
vm_config->type = UNDEFINED_VM;
47+
return vm_id;
5948
}
6049

6150
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_
363352
register_mmio_default_emulation_handler(vm);
364353
}
365354

355+
(void)memcpy_s(&vm->uuid[0], sizeof(vm->uuid),
356+
&vm_config->uuid[0], sizeof(vm_config->uuid));
357+
366358
if (is_sos_vm(vm)) {
367359
/* Only for SOS_VM */
368360
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_
392384
snprintf(vm_config->name, 16, "ACRN VM_%d", vm_id);
393385
}
394386

395-
(void)memcpy_s(&vm->uuid[0], sizeof(vm->uuid),
396-
&vm_config->uuid[0], sizeof(vm_config->uuid));
397-
398387
if (vm_config->type == PRE_LAUNCHED_VM) {
399388
create_prelaunched_vm_e820(vm);
400389
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_
469458
if (vm->arch_vm.nworld_eptp != NULL) {
470459
(void)memset(vm->arch_vm.nworld_eptp, 0U, PAGE_SIZE);
471460
}
472-
free_vm_id(vm);
473461
}
474462
return status;
475463
}
@@ -506,9 +494,6 @@ int32_t shutdown_vm(struct acrn_vm *vm)
506494
/* Free EPT allocated resources assigned to VM */
507495
destroy_ept(vm);
508496

509-
/* Free vm id */
510-
free_vm_id(vm);
511-
512497
ret = 0;
513498
} else {
514499
ret = -EINVAL;

hypervisor/common/hypercall.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,10 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param)
126126

127127
(void)memset((void *)&cv, 0U, sizeof(cv));
128128
if (copy_from_gpa(vm, &cv, param, sizeof(cv)) == 0) {
129-
/* check whether there is a free vm id for use */
130-
/* TODO: pass vm id from DM to make vm_id static */
131-
vm_id = find_free_vm_id();
129+
vm_id = get_vmid_by_uuid(&cv.uuid[0]);
132130
if (vm_id < CONFIG_MAX_VM_NUM) {
133131
vm_config = get_vm_config(vm_id);
134-
/* TODO: set by DM */
135-
vm_config->type = NORMAL_VM;
136132
vm_config->guest_flags |= cv.vm_flag;
137-
(void)memcpy_s(&vm_config->uuid[0], 16U, &cv.uuid[0], 16U);
138133

139134
/* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */
140135
if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U)

hypervisor/include/arch/x86/guest/vm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ void launch_vms(uint16_t pcpu_id);
213213
bool is_valid_vm(const struct acrn_vm *vm);
214214
bool is_sos_vm(const struct acrn_vm *vm);
215215
bool is_prelaunched_vm(const struct acrn_vm *vm);
216-
uint16_t find_free_vm_id(void);
216+
uint16_t get_vmid_by_uuid(const uint8_t *uuid);
217217
struct acrn_vm *get_vm_from_vmid(uint16_t vm_id);
218218
struct acrn_vm *get_sos_vm(void);
219219

hypervisor/include/arch/x86/vm_config.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct acrn_vm_pci_ptdev_config {
4545
struct acrn_vm_config {
4646
enum acrn_vm_type type; /* specify the type of VM */
4747
char name[MAX_VM_OS_NAME_LEN]; /* VM name identifier, useful for debug. */
48-
uint8_t uuid[16]; /* UUID of the VM */
48+
const uint8_t uuid[16]; /* UUID of the VM */
4949
uint64_t pcpu_bitmap; /* from pcpu bitmap, we could know VM core number */
5050
uint64_t guest_flags; /* VM flags that we want to configure for guest
5151
* Now we have two flags:
@@ -63,6 +63,7 @@ struct acrn_vm_config {
6363
} __aligned(8);
6464

6565
struct acrn_vm_config *get_vm_config(uint16_t vm_id);
66+
bool vm_has_matched_uuid(uint16_t vmid, const uint8_t *uuid);
6667
bool sanitize_vm_config(void);
6768

6869
extern struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM];

hypervisor/scenarios/logical_partition/vm_configurations.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
1515
{ /* VM0 */
1616
.type = PRE_LAUNCHED_VM,
1717
.name = "ACRN PRE-LAUNCHED VM0",
18+
.uuid = {0x26U, 0xc5U, 0xe0U, 0xd8U, 0x8fU, 0x8aU, 0x47U, 0xd8U, \
19+
0x81U, 0x09U, 0xf2U, 0x01U, 0xebU, 0xd6U, 0x1aU, 0x5eU},
20+
/* 26c5e0d8-8f8a-47d8-8109-f201ebd61a5e */
1821
.pcpu_bitmap = VM0_CONFIG_PCPU_BITMAP,
1922
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
2023
.clos = 0U,
@@ -38,6 +41,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
3841
{ /* VM1 */
3942
.type = PRE_LAUNCHED_VM,
4043
.name = "ACRN PRE-LAUNCHED VM1",
44+
.uuid = {0xddU, 0x87U, 0xceU, 0x08U, 0x66U, 0xf9U, 0x47U, 0x3dU, \
45+
0xbcU, 0x58U, 0x76U, 0x05U, 0x83U, 0x7fU, 0x93U, 0x5eU},
46+
/* dd87ce08-66f9-473d-bc58-7605837f935e */
4147
.pcpu_bitmap = VM1_CONFIG_PCPU_BITMAP,
4248
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
4349
.clos = 0U,

hypervisor/scenarios/sdc/vm_configurations.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
1212
{
1313
.type = SOS_VM,
1414
.name = "ACRN SOS VM",
15+
.uuid = {0xdbU, 0xbbU, 0xd4U, 0x34U, 0x7aU, 0x57U, 0x42U, 0x16U, \
16+
0xa1U, 0x2cU, 0x22U, 0x01U, 0xf1U, 0xabU, 0x02U, 0x40U},
17+
/* dbbbd434-7a57-4216-a12c-2201f1ab0240 */
1518
.guest_flags = GUEST_FLAG_IO_COMPLETION_POLLING,
1619
.clos = 0U,
1720
.memory = {
@@ -22,4 +25,10 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
2225
.name = "ACRN Service OS",
2326
},
2427
},
28+
{
29+
.type = NORMAL_VM,
30+
.uuid = {0xd2U, 0x79U, 0x54U, 0x38U, 0x25U, 0xd6U, 0x11U, 0xe8U, \
31+
0x86U, 0x4eU, 0xcbU, 0x7aU, 0x18U, 0xb3U, 0x46U, 0x43U},
32+
/* d2795438-25d6-11e8-864e-cb7a18b34643 */
33+
}
2534
};

0 commit comments

Comments
 (0)