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);
 }
 
 /**