Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152929517
D52781.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D52781.id.diff
View Options
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -276,6 +276,7 @@
&vm_maxcpu, 0, "Maximum number of vCPUs");
static void vcpu_notify_event_locked(struct vcpu *vcpu, bool lapic_intr);
+static int vm_handle_rendezvous(struct vcpu *vcpu, bool wait);
/* global statistics */
VMM_STAT(VCPU_MIGRATIONS, "vcpu migration across host cpus");
@@ -997,7 +998,9 @@
vcpu_set_state_locked(struct vcpu *vcpu, enum vcpu_state newstate,
bool from_idle)
{
+ struct vcpu *rendezvous_vcpu;
int error;
+ uint16_t maxcpus;
vcpu_assert_locked(vcpu);
@@ -1012,6 +1015,30 @@
vcpu_notify_event_locked(vcpu, false);
VMM_CTR1(vcpu, "vcpu state change from %s to "
"idle requested", vcpu_state2str(vcpu->state));
+ /*
+ * If the vCPU we're requesting a state change for, is currently
+ * waiting for rendezvous completion, we're going to deadlock
+ * because we're waiting for the other vCPU to transition to IDLE
+ * and the other vCPU waits for us completing the rendezvous.
+ * Therefore, we have to handle any pending rendezvous.
+ */
+ if (__predict_false(
+ atomic_load_ptr(&vcpu->vm->rendezvous_func) !=
+ NULL)) {
+ vcpu_unlock(vcpu);
+ maxcpus = vm_get_maxcpus(vcpu->vm);
+ for (uint16_t i = 0; i < maxcpus; i++) {
+ rendezvous_vcpu = vm_vcpu(vcpu->vm, i);
+ if (rendezvous_vcpu == NULL)
+ continue;
+ vm_handle_rendezvous(rendezvous_vcpu, false);
+ }
+ vcpu_lock(vcpu);
+ /* Recheck vCPU state to avoid an unnecessary sleep. */
+ if (vcpu->state == VCPU_IDLE) {
+ break;
+ }
+ }
msleep_spin(&vcpu->state, &vcpu->mtx, "vmstat", hz);
}
} else {
@@ -1084,7 +1111,7 @@
}
static int
-vm_handle_rendezvous(struct vcpu *vcpu)
+vm_handle_rendezvous(struct vcpu *vcpu, bool wait)
{
struct vm *vm = vcpu->vm;
struct thread *td;
@@ -1112,6 +1139,12 @@
wakeup(&vm->rendezvous_func);
break;
}
+
+ if (!wait) {
+ mtx_unlock(&vm->rendezvous_mtx);
+ return (0);
+ }
+
VMM_CTR0(vcpu, "Wait for rendezvous completion");
mtx_sleep(&vm->rendezvous_func, &vm->rendezvous_mtx, 0,
"vmrndv", hz);
@@ -1386,7 +1419,7 @@
} else {
VMM_CTR0(vcpu, "Rendezvous during suspend");
vcpu_unlock(vcpu);
- error = vm_handle_rendezvous(vcpu);
+ error = vm_handle_rendezvous(vcpu, true);
vcpu_lock(vcpu);
}
}
@@ -1602,7 +1635,7 @@
vioapic_process_eoi(vm, vme->u.ioapic_eoi.vector);
break;
case VM_EXITCODE_RENDEZVOUS:
- error = vm_handle_rendezvous(vcpu);
+ error = vm_handle_rendezvous(vcpu, true);
break;
case VM_EXITCODE_HLT:
intr_disabled = ((vme->u.hlt.rflags & PSL_I) == 0);
@@ -2345,7 +2378,7 @@
*/
VMM_CTR0(vcpu, "Rendezvous already in progress");
mtx_unlock(&vm->rendezvous_mtx);
- error = vm_handle_rendezvous(vcpu);
+ error = vm_handle_rendezvous(vcpu, true);
if (error != 0)
return (error);
goto restart;
@@ -2369,7 +2402,7 @@
vcpu_notify_event(vm_vcpu(vm, i), false);
}
- return (vm_handle_rendezvous(vcpu));
+ return (vm_handle_rendezvous(vcpu, true));
}
struct vatpic *
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 19, 3:36 AM (9 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31744321
Default Alt Text
D52781.id.diff (3 KB)
Attached To
Mode
D52781: sys/amd64/vmm: fix Windows 11 deadlock
Attached
Detach File
Event Timeline
Log In to Comment