Ensure that register state is saved before it's used.
Without this there is a race where a physical CPU is still saving the
contents of registers into a vCPU buffer while another physical CPU
is already trying to restore the state.
Also adding test case that fails without this fix and succeeds with it.
Change-Id: I0badfd61f12385a3d8dc8d09eb298cfe56f2a415
diff --git a/src/vm.c b/src/vm.c
index f1fcbb6..4a1d9d7 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -42,6 +42,10 @@
vm->vcpu_count = vcpu_count;
vm->mailbox.state = mailbox_state_empty;
+ if (!mm_ptable_init(&vm->ptable, 0, ppool)) {
+ return false;
+ }
+
/* Do basic initialization of vcpus. */
for (i = 0; i < vcpu_count; i++) {
vcpu_init(&vm->vcpus[i], vm);
@@ -50,7 +54,7 @@
++vm_count;
*new_vm = vm;
- return mm_ptable_init(&vm->ptable, 0, ppool);
+ return true;
}
uint32_t vm_get_count(void)
@@ -73,8 +77,7 @@
{
struct vcpu *vcpu = &vm->vcpus[index];
if (index < vm->vcpu_count) {
- arch_regs_init(&vcpu->regs, vm->id == HF_PRIMARY_VM_ID, vm->id,
- vm->ptable.root, entry, arg);
+ arch_regs_set_pc_arg(&vcpu->regs, entry, arg);
vcpu_on(vcpu);
}
}