Store all VMs together.
In preparation for the primary VM becoming less special, particularly in
the context of IPC where any VM will be able to talk to any other VM.
The primary VM takes ID 0 and the secondary VMs take the IDs from 1.
`hf_vm_get_count()` now returns the total number of VMs including the
primary.
`hf_rpc_request()` block reflexive calls as there is no good reason for
them and the error has the chance of catching bugs in the calling VM.
Change-Id: Ic95ef0ab8b967bbbd3232c207c53074cff8e138d
diff --git a/src/vm.c b/src/vm.c
index d2beeb0..0958682 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -4,13 +4,25 @@
#include "hf/cpu.h"
#include "hf/std.h"
-bool vm_init(struct vm *vm, uint32_t id, uint32_t vcpu_count)
+#include "vmapi/hf/call.h"
+
+static struct vm vms[MAX_VMS];
+static uint32_t vm_count;
+
+bool vm_init(uint32_t vcpu_count, struct vm **new_vm)
{
uint32_t i;
+ struct vm *vm;
+
+ if (vm_count >= MAX_VMS) {
+ return false;
+ }
+
+ vm = &vms[vm_count];
memset(vm, 0, sizeof(*vm));
- vm->id = id;
+ vm->id = vm_count;
vm->vcpu_count = vcpu_count;
vm->rpc.state = rpc_state_idle;
@@ -19,9 +31,27 @@
vcpu_init(&vm->vcpus[i], vm);
}
+ ++vm_count;
+ *new_vm = vm;
+
return mm_ptable_init(&vm->ptable, 0);
}
+uint32_t vm_get_count(void)
+{
+ return vm_count;
+}
+
+struct vm *vm_get(uint32_t id)
+{
+ /* Ensure the VM is initialized. */
+ if (id >= vm_count) {
+ return NULL;
+ }
+
+ return &vms[id];
+}
+
/* TODO: Shall we use index or id here? */
void vm_start_vcpu(struct vm *vm, size_t index, ipaddr_t entry, size_t arg)
{
@@ -34,6 +64,6 @@
void vm_set_current(struct vm *vm)
{
- arch_cpu_update(vm == &primary_vm);
+ arch_cpu_update(vm->id == HF_PRIMARY_VM_ID);
arch_mm_set_vm(vm->id, vm->ptable.table);
}