Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144383940
D37390.id113176.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D37390.id113176.diff
View Options
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -313,10 +313,9 @@
#endif /* _SYS__CPUSET_H_ */
static __inline int
-vcpu_rendezvous_pending(struct vm_eventinfo *info)
+vcpu_rendezvous_pending(int vcpuid, struct vm_eventinfo *info)
{
-
- return (*((uintptr_t *)(info->rptr)) != 0);
+ return CPU_ISSET(vcpuid, (cpuset_t *)info->rptr);
}
static __inline int
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -2066,7 +2066,7 @@
break;
}
- if (vcpu_rendezvous_pending(evinfo)) {
+ if (vcpu_rendezvous_pending(vcpu, evinfo)) {
enable_gintr();
vm_exit_rendezvous(vm, vcpu, state->rip);
break;
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -3065,7 +3065,7 @@
break;
}
- if (vcpu_rendezvous_pending(evinfo)) {
+ if (vcpu_rendezvous_pending(vcpu, evinfo)) {
enable_intr();
vm_exit_rendezvous(vmx->vm, vcpu, rip);
break;
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
@@ -1325,6 +1325,20 @@
&vm->rendezvous_done_cpus) == 0) {
VCPU_CTR0(vm, vcpuid, "Rendezvous completed");
vm->rendezvous_func = NULL;
+ /*
+ * Clear the rendezvous_req_cpus to avoid that any vcpu
+ * tries to reenter the rendezvous. We don't need any
+ * memory barrier/order here because:
+ * 1. The field is cleared. So, no additional vcpu will
+ * try to enter the rendezvous.
+ * 2. All vcpus that take part in the rendezvous are
+ * sleeping at mtx_sleep a few lines below.
+ * 3. This code is protected by rendezvous_mtx which
+ * ensures that all vcpu taking part at the
+ * rendezvous will see an empty rendezvous_req_cpus
+ * when they exit the rendezvous.
+ */
+ CPU_ZERO(&vm->rendezvous_req_cpus);
wakeup(&vm->rendezvous_func);
break;
}
@@ -1755,7 +1769,7 @@
pmap = vmspace_pmap(vm->vmspace);
vcpu = &vm->vcpu[vcpuid];
vme = &vcpu->exitinfo;
- evinfo.rptr = &vm->rendezvous_func;
+ evinfo.rptr = &vm->rendezvous_req_cpus;
evinfo.sptr = &vm->suspend;
evinfo.iptr = &vcpu->reqidle;
restart:
@@ -2616,10 +2630,17 @@
"rendezvous is still in progress"));
RENDEZVOUS_CTR0(vm, vcpuid, "Initiating rendezvous");
- vm->rendezvous_req_cpus = dest;
CPU_ZERO(&vm->rendezvous_done_cpus);
vm->rendezvous_arg = arg;
vm->rendezvous_func = func;
+ /*
+ * If a vcpu sees that it's vcpu bit is set in rendezvous_req_cpus,
+ * it'll try to enter the rendezvous code. Therefore, make sure that all
+ * rendezvous parameter are seen by all vcpus before setting
+ * rendezvous_req_cpus.
+ */
+ rmb();
+ vm->rendezvous_req_cpus = dest;
mtx_unlock(&vm->rendezvous_mtx);
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 4:15 AM (20 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28535472
Default Alt Text
D37390.id113176.diff (2 KB)
Attached To
Mode
D37390: vmm: avoid spurios rendezvous
Attached
Detach File
Event Timeline
Log In to Comment