aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/vmm
diff options
context:
space:
mode:
authorCorvin Köhne <corvink@FreeBSD.org>2022-11-15 10:53:49 +0000
committerCorvin Köhne <corvink@FreeBSD.org>2023-02-08 09:28:47 +0000
commit7148611e4f560f375d4b92fdeb9451a792dc73fc (patch)
tree4d9f4672b40802d5906186868f2159d403ae3803 /sys/amd64/vmm
parentc8452bdeed4fc1f1feadf36c6008367263292254 (diff)
vmm: avoid spurious rendezvous
A vcpu only checks if a rendezvous is in progress or not to decide if it should handle a rendezvous. This could lead to spurios rendezvous where a vcpu tries a handle a rendezvous it isn't part of. This situation is properly handled by vm_handle_rendezvous but it could potentially degrade the performance. Avoid that by an early check if the vcpu is part of the rendezvous or not. At the moment, rendezvous are only used to spin up application processors and to send ioapic interrupts. Spinning up application processors is done in the guest boot phase by sending INIT SIPI sequences to single vcpus. This is known to cause spurious rendezvous and only occurs in the boot phase. Sending ioapic interrupts is rare because modern guest will use msi and the rendezvous is always send to all vcpus. Reviewed by: jhb MFC after: 1 week Sponsored by: Beckhoff Automation GmbH & Co. KG Differential Revision: https://reviews.freebsd.org/D37390 (cherry picked from commit 892feec2211d0dbd58252a34d78dbcb2d5dd7593)
Diffstat (limited to 'sys/amd64/vmm')
-rw-r--r--sys/amd64/vmm/amd/svm.c2
-rw-r--r--sys/amd64/vmm/intel/vmx.c2
-rw-r--r--sys/amd64/vmm/vmm.c3
3 files changed, 4 insertions, 3 deletions
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index 2448501401e3..ee1154ef85b6 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -2053,7 +2053,7 @@ svm_run(void *vcpui, register_t rip, pmap_t pmap, struct vm_eventinfo *evinfo)
break;
}
- if (vcpu_rendezvous_pending(evinfo)) {
+ if (vcpu_rendezvous_pending(vcpu->vcpu, evinfo)) {
enable_gintr();
vm_exit_rendezvous(vcpu->vcpu, state->rip);
break;
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 4b65e254cc91..fa94c707001c 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -3071,7 +3071,7 @@ vmx_run(void *vcpui, register_t rip, pmap_t pmap, struct vm_eventinfo *evinfo)
break;
}
- if (vcpu_rendezvous_pending(evinfo)) {
+ if (vcpu_rendezvous_pending(vcpu->vcpu, evinfo)) {
enable_intr();
vm_exit_rendezvous(vcpu->vcpu, rip);
break;
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index f0ee159dcbb9..123d35a983c0 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -1438,6 +1438,7 @@ vm_handle_rendezvous(struct vcpu *vcpu)
if (CPU_CMP(&vm->rendezvous_req_cpus,
&vm->rendezvous_done_cpus) == 0) {
VMM_CTR0(vcpu, "Rendezvous completed");
+ CPU_ZERO(&vm->rendezvous_req_cpus);
vm->rendezvous_func = NULL;
wakeup(&vm->rendezvous_func);
break;
@@ -1858,7 +1859,7 @@ vm_run(struct vcpu *vcpu, struct vm_exit *vme_user)
pmap = vmspace_pmap(vm->vmspace);
vme = &vcpu->exitinfo;
- evinfo.rptr = &vm->rendezvous_func;
+ evinfo.rptr = &vm->rendezvous_req_cpus;
evinfo.sptr = &vm->suspend;
evinfo.iptr = &vcpu->reqidle;
restart: