summaryrefslogtreecommitdiff
path: root/usr.sbin/vmd
diff options
context:
space:
mode:
authorDave Voutila <dv@cvs.openbsd.org>2023-09-26 01:23:03 +0000
committerDave Voutila <dv@cvs.openbsd.org>2023-09-26 01:23:03 +0000
commit72e6fdbb6d6a55641e4102bd4460a25351a6f3f5 (patch)
tree40528ac600d842728a97cd967a6d3736ae125b49 /usr.sbin/vmd
parentcb0b059d83bc2cf2851404fe7b5c38e904a790ab (diff)
vmd(8): fix vm pause deadlock.
When vcpu threads pause, they are holding the run mutex lock. If the event thread is asked to assert an irq on the pic and interrupts are pending, it will try to take the run mutex lock on the vcpu. This deadlocks. Release the lock in the vcpu thread before waiting on the pause condition variable. ok mlarkin@
Diffstat (limited to 'usr.sbin/vmd')
-rw-r--r--usr.sbin/vmd/vm.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/usr.sbin/vmd/vm.c b/usr.sbin/vmd/vm.c
index fe804b4e3b9..115a60c3683 100644
--- a/usr.sbin/vmd/vm.c
+++ b/usr.sbin/vmd/vm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm.c,v 1.92 2023/09/23 12:27:21 dv Exp $ */
+/* $OpenBSD: vm.c,v 1.93 2023/09/26 01:23:02 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -1565,6 +1565,8 @@ vcpu_run_loop(void *arg)
return ((void *)ret);
}
+ /* i8259 may be firing as we pause, release run mtx. */
+ mutex_unlock(&vcpu_run_mtx[n]);
ret = pthread_cond_wait(&vcpu_unpause_cond[n],
&vcpu_unpause_mtx[n]);
if (ret) {
@@ -1573,6 +1575,8 @@ vcpu_run_loop(void *arg)
__func__, (int)ret);
break;
}
+ mutex_lock(&vcpu_run_mtx[n]);
+
ret = pthread_mutex_unlock(&vcpu_unpause_mtx[n]);
if (ret) {
log_warnx("%s: can't unlock unpause mtx (%d)",
@@ -2136,18 +2140,12 @@ vcpu_assert_pic_irq(uint32_t vm_id, uint32_t vcpu_id, int irq)
if (i8259_is_pending()) {
if (vcpu_pic_intr(vm_id, vcpu_id, 1))
fatalx("%s: can't assert INTR", __func__);
-
- ret = pthread_mutex_lock(&vcpu_run_mtx[vcpu_id]);
- if (ret)
- fatalx("%s: can't lock vcpu mtx (%d)", __func__, ret);
-
+ mutex_lock(&vcpu_run_mtx[vcpu_id]);
vcpu_hlt[vcpu_id] = 0;
ret = pthread_cond_signal(&vcpu_run_cond[vcpu_id]);
if (ret)
fatalx("%s: can't signal (%d)", __func__, ret);
- ret = pthread_mutex_unlock(&vcpu_run_mtx[vcpu_id]);
- if (ret)
- fatalx("%s: can't unlock vcpu mtx (%d)", __func__, ret);
+ mutex_unlock(&vcpu_run_mtx[vcpu_id]);
}
}