Generate VM IDs with an offset of 1
The SMCCC reserves VM ID 0 for the hypervisor itself, therefore, other VM IDs
should start after that (at least, but not necessarily at 1).
- Generate VM IDs with an offset defined by HF_VM_ID_OFFSET (currently 1)
- Fix hardcoded IDs and other code that assumes VM IDs start at 0.
Bug: 132421503
Change-Id: I47cff8734ac153dcb1a1a435285153d6caf2877e
diff --git a/driver/linux b/driver/linux
index 8523ccd..5da4b6b 160000
--- a/driver/linux
+++ b/driver/linux
@@ -1 +1 @@
-Subproject commit 8523ccdc881535a45b0c95aa12645c95aa7fc9f8
+Subproject commit 5da4b6b4a3a24e7e3eb4dc5aabd0e601d5673aad
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index cad5e35..99664ed 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -67,7 +67,7 @@
/* clang-format on */
-/** The ID of a VM. These are assigned sequentially. */
+/** The ID of a VM. These are assigned sequentially starting with an offset. */
typedef uint16_t spci_vm_id_t;
typedef uint32_t spci_memory_handle_t;
diff --git a/inc/vmapi/hf/types.h b/inc/vmapi/hf/types.h
index 0479012..f54d7d7 100644
--- a/inc/vmapi/hf/types.h
+++ b/inc/vmapi/hf/types.h
@@ -33,10 +33,21 @@
#endif
-/** The ID of the primary VM which is responsible for scheduling. */
-#define HF_PRIMARY_VM_ID 0
+/**
+ * An offset to use when assigning VM IDs.
+ * The offset is needed because VM ID 0 is reserved.
+ */
+#define HF_VM_ID_OFFSET 1
-/* Sleep value for an indefinite period of time. */
+/**
+ * The ID of the primary VM, which is responsible for scheduling.
+ *
+ * Starts at the offset because ID 0 is reserved for the hypervisor itself.
+ * All other VM IDs come after the primary.
+ */
+#define HF_PRIMARY_VM_ID HF_VM_ID_OFFSET
+
+/** Sleep value for an indefinite period of time. */
#define HF_SLEEP_INDEFINITE 0xffffffffffffff
/** The amount of data that can be sent to a mailbox. */
diff --git a/src/vm.c b/src/vm.c
index fd477cd..08e9531 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -27,6 +27,15 @@
static struct vm vms[MAX_VMS];
static spci_vm_count_t vm_count;
+/**
+ * Returns the index of the VM within the VM array.
+ */
+static uint16_t vm_get_vm_index(spci_vm_id_t vm_id)
+{
+ CHECK(vm_id >= HF_VM_ID_OFFSET);
+ return vm_id - HF_VM_ID_OFFSET;
+}
+
bool vm_init(spci_vcpu_count_t vcpu_count, struct mpool *ppool,
struct vm **new_vm)
{
@@ -45,7 +54,8 @@
list_init(&vm->mailbox.ready_list);
sl_init(&vm->lock);
- vm->id = vm_count;
+ /* Generate IDs based on an offset, as low IDs e.g., 0, are reserved */
+ vm->id = vm_count + HF_VM_ID_OFFSET;
vm->vcpu_count = vcpu_count;
vm->mailbox.state = MAILBOX_STATE_EMPTY;
atomic_init(&vm->aborting, false);
@@ -79,12 +89,14 @@
struct vm *vm_find(spci_vm_id_t id)
{
+ uint16_t vm_index = vm_get_vm_index(id);
+
/* Ensure the VM is initialized. */
- if (id >= vm_count) {
+ if (vm_index >= vm_count) {
return NULL;
}
- return &vms[id];
+ return &vms[vm_index];
}
/**
diff --git a/test/vmapi/gicv3/busy_secondary.c b/test/vmapi/gicv3/busy_secondary.c
index 4631312..2f0766a 100644
--- a/test/vmapi/gicv3/busy_secondary.c
+++ b/test/vmapi/gicv3/busy_secondary.c
@@ -81,8 +81,7 @@
dlog("Telling secondary to loop.\n");
memcpy_s(send_buffer->payload, SPCI_MSG_PAYLOAD_MAX, message,
sizeof(message));
- spci_message_init(send_buffer, 0, SERVICE_VM0,
- recv_buffer->target_vm_id);
+ spci_message_init(send_buffer, 0, SERVICE_VM0, HF_PRIMARY_VM_ID);
EXPECT_EQ(spci_msg_send(0), 0);
run_res = hf_vcpu_run(SERVICE_VM0, 0);
EXPECT_EQ(run_res.code, HF_VCPU_RUN_PREEMPTED);
@@ -139,8 +138,7 @@
dlog("Telling secondary to loop.\n");
memcpy_s(send_buffer->payload, SPCI_MSG_PAYLOAD_MAX, message,
sizeof(message));
- spci_message_init(send_buffer, 0, SERVICE_VM0,
- recv_buffer->target_vm_id);
+ spci_message_init(send_buffer, 0, SERVICE_VM0, HF_PRIMARY_VM_ID);
EXPECT_EQ(spci_msg_send(0), 0);
run_res = hf_vcpu_run(SERVICE_VM0, 0);
EXPECT_EQ(run_res.code, HF_VCPU_RUN_PREEMPTED);
diff --git a/test/vmapi/gicv3/inc/gicv3.h b/test/vmapi/gicv3/inc/gicv3.h
index 264dc0c..d51398f 100644
--- a/test/vmapi/gicv3/inc/gicv3.h
+++ b/test/vmapi/gicv3/inc/gicv3.h
@@ -25,7 +25,7 @@
#define NANOS_PER_UNIT 1000000000
-#define SERVICE_VM0 1
+#define SERVICE_VM0 (HF_VM_ID_OFFSET + 1)
extern alignas(PAGE_SIZE) uint8_t send_page[PAGE_SIZE];
extern alignas(PAGE_SIZE) uint8_t recv_page[PAGE_SIZE];
diff --git a/test/vmapi/primary_only/primary_only.c b/test/vmapi/primary_only/primary_only.c
index fcebccb..a7b29c8 100644
--- a/test/vmapi/primary_only/primary_only.c
+++ b/test/vmapi/primary_only/primary_only.c
@@ -45,7 +45,7 @@
*/
TEST(hf_vcpu_get_count, primary_has_at_least_one)
{
- EXPECT_GE(hf_vcpu_get_count(0), 0);
+ EXPECT_GE(hf_vcpu_get_count(HF_PRIMARY_VM_ID), 0);
}
/**
@@ -54,7 +54,7 @@
*/
TEST(hf_vcpu_get_count, no_secondary_vms)
{
- EXPECT_EQ(hf_vcpu_get_count(1), 0);
+ EXPECT_EQ(hf_vcpu_get_count(HF_VM_ID_OFFSET + 1), 0);
}
/**
@@ -148,10 +148,10 @@
* can't optimise them away.
*/
double a = hf_vm_get_count();
- double b = hf_vcpu_get_count(0);
+ double b = hf_vcpu_get_count(HF_PRIMARY_VM_ID);
double result = a * b;
dlog("VM count: %d\n", hf_vm_get_count());
- dlog("vCPU count: %d\n", hf_vcpu_get_count(0));
+ dlog("vCPU count: %d\n", hf_vcpu_get_count(HF_PRIMARY_VM_ID));
dlog("result: %d\n", (int)result);
EXPECT_TRUE(a == 1.0);
EXPECT_TRUE(b == 8.0);
diff --git a/test/vmapi/primary_with_secondaries/inc/primary_with_secondary.h b/test/vmapi/primary_with_secondaries/inc/primary_with_secondary.h
index a8ff882..9e20650 100644
--- a/test/vmapi/primary_with_secondaries/inc/primary_with_secondary.h
+++ b/test/vmapi/primary_with_secondaries/inc/primary_with_secondary.h
@@ -16,9 +16,9 @@
#pragma once
-#define SERVICE_VM0 1
-#define SERVICE_VM1 2
-#define SERVICE_VM2 3
+#define SERVICE_VM0 (HF_VM_ID_OFFSET + 1)
+#define SERVICE_VM1 (HF_VM_ID_OFFSET + 2)
+#define SERVICE_VM2 (HF_VM_ID_OFFSET + 3)
#define SELF_INTERRUPT_ID 5
#define EXTERNAL_INTERRUPT_ID_A 7
diff --git a/test/vmapi/primary_with_secondaries/no_services.c b/test/vmapi/primary_with_secondaries/no_services.c
index 7b171e8..975ea6d 100644
--- a/test/vmapi/primary_with_secondaries/no_services.c
+++ b/test/vmapi/primary_with_secondaries/no_services.c
@@ -55,7 +55,7 @@
*/
TEST(hf_vcpu_get_count, secondary_has_one_vcpu)
{
- EXPECT_EQ(hf_vcpu_get_count(1), 1);
+ EXPECT_EQ(hf_vcpu_get_count(SERVICE_VM0), 1);
}
/**