summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authoranton <anton@cvs.openbsd.org>2019-09-11 16:55:54 +0000
committeranton <anton@cvs.openbsd.org>2019-09-11 16:55:54 +0000
commit439c1ac46ef55f839cbcf61ab7414bb2e8fb0498 (patch)
tree0ade2e4f29257b1c357c85a41fd3d44b585633de /sys/arch
parent682c42190b52237f52c1e21ccdb2e84a91de84a9 (diff)
vm_teardown() must be serialized since it modifies the global vmm_softc
structure. Therefore grab the appropriate lock before calling the same function. This issue has been known for a while and reported before but lacking a way to easily reproduce it; until syzkaller came up with a reproducer. ok mlarkin@ Reported-by: syzbot+39ff060789d93be0084f@syzkaller.appspotmail.com
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/amd64/amd64/vmm.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/arch/amd64/amd64/vmm.c b/sys/arch/amd64/amd64/vmm.c
index ac836690ab6..35c571e2a0b 100644
--- a/sys/arch/amd64/amd64/vmm.c
+++ b/sys/arch/amd64/amd64/vmm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmm.c,v 1.252 2019/09/10 19:36:12 anton Exp $ */
+/* $OpenBSD: vmm.c,v 1.253 2019/09/11 16:55:53 anton Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
@@ -1161,14 +1161,16 @@ vm_create(struct vm_create_params *vcp, struct proc *p)
vm->vm_memory_size = memsize;
strncpy(vm->vm_name, vcp->vcp_name, VMM_MAX_NAME_LEN);
+ rw_enter_write(&vmm_softc->vm_lock);
+
if (vm_impl_init(vm, p)) {
printf("failed to init arch-specific features for vm 0x%p\n",
vm);
vm_teardown(vm);
+ rw_exit_write(&vmm_softc->vm_lock);
return (ENOMEM);
}
- rw_enter_write(&vmm_softc->vm_lock);
vmm_softc->vm_ct++;
vmm_softc->vm_idx++;
@@ -3408,6 +3410,8 @@ vm_teardown(struct vm *vm)
{
struct vcpu *vcpu, *tmp;
+ rw_assert_wrlock(&vmm_softc->vm_lock);
+
/* Free VCPUs */
rw_enter_write(&vm->vm_vcpu_lock);
SLIST_FOREACH_SAFE(vcpu, &vm->vm_vcpu_list, vc_vcpu_link, tmp) {
@@ -3910,8 +3914,11 @@ vm_run(struct vm_run_params *vrp)
if (vcpu->vc_state == VCPU_STATE_REQTERM) {
vrp->vrp_exit_reason = VM_EXIT_TERMINATED;
vcpu->vc_state = VCPU_STATE_TERMINATED;
- if (vm->vm_vcpus_running == 0)
+ if (vm->vm_vcpus_running == 0) {
+ rw_enter_write(&vmm_softc->vm_lock);
vm_teardown(vm);
+ rw_exit_write(&vmm_softc->vm_lock);
+ }
ret = 0;
} else if (ret == EAGAIN) {
/* If we are exiting, populate exit data so vmd can help. */