git: 7c326ab5bb9a - main - vmm: don't lock a mtx in the icr_low write handler
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 23 Nov 2022 08:00:16 UTC
The branch main has been updated by corvink:
URL: https://cgit.FreeBSD.org/src/commit/?id=7c326ab5bb9aced8dcbc2465ac1c9ff8df2ba46b
commit 7c326ab5bb9aced8dcbc2465ac1c9ff8df2ba46b
Author: Corvin Köhne <corvink@FreeBSD.org>
AuthorDate: 2022-11-21 14:00:04 +0000
Commit: Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2022-11-23 08:00:04 +0000
vmm: don't lock a mtx in the icr_low write handler
x2apic accesses are handled by a wrmsr exit. This handler is called in a
critical section. So, we can't lock a mtx in the icr_low handler.
Reported by: kp, pho
Tested by: kp, pho
Approved by: manu (mentor)
Fixes: c0f35dbf19c3c8825bd2b321d8efd582807d1940 vmm: Use a cpuset_t for vCPUs waiting for STARTUP IPIs.
MFC after: 1 week
MFC with: c0f35dbf19c3c8825bd2b321d8efd582807d1940
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D37452
---
sys/amd64/vmm/io/vlapic.c | 61 +++++++++++++++++++++++++++--------------------
1 file changed, 35 insertions(+), 26 deletions(-)
diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c
index 6307ce341c72..44641cc29035 100644
--- a/sys/amd64/vmm/io/vlapic.c
+++ b/sys/amd64/vmm/io/vlapic.c
@@ -1127,9 +1127,8 @@ vlapic_icrlo_write_handler(struct vlapic *vlapic, bool *retu)
i == vlapic->vcpuid)
break;
- /* vCPU i is waiting for SIPI. */
- CPU_SETOF(i, &dmask);
- vm_await_start(vlapic->vm, &dmask);
+ CPU_SETOF(i, &ipimask);
+
break;
}
@@ -1140,36 +1139,17 @@ vlapic_icrlo_write_handler(struct vlapic *vlapic, bool *retu)
if (!phys)
break;
- /*
- * Old bhyve versions don't support the IPI
- * exit. Translate it into the old style.
- */
i = vm_apicid2vcpuid(vlapic->vm, dest);
if (i >= vm_get_maxcpus(vlapic->vm) ||
i == vlapic->vcpuid)
break;
- /*
- * Ignore SIPIs in any state other than wait-for-SIPI
- */
- CPU_SETOF(i, &dmask);
- dmask = vm_start_cpus(vlapic->vm, &dmask);
- if (CPU_EMPTY(&dmask))
- break;
-
- vmexit = vm_exitinfo(vlapic->vcpu);
- vmexit->exitcode = VM_EXITCODE_SPINUP_AP;
- vmexit->u.spinup_ap.vcpu = i;
- vmexit->u.spinup_ap.rip = vec << PAGE_SHIFT;
+ CPU_SETOF(i, &ipimask);
- *retu = true;
break;
}
- /*
- * Ignore SIPIs in any state other than wait-for-SIPI
- */
- ipimask = vm_start_cpus(vlapic->vm, &dmask);
+ CPU_COPY(&dmask, &ipimask);
break;
default:
return (1);
@@ -1199,14 +1179,43 @@ vlapic_handle_init(struct vcpu *vcpu, void *arg)
int
vm_handle_ipi(struct vcpu *vcpu, struct vm_exit *vme, bool *retu)
{
+ struct vlapic *vlapic = vm_lapic(vcpu);
+ cpuset_t *dmask = &vme->u.ipi.dmask;
+ uint8_t vec = vme->u.ipi.vector;
+
*retu = true;
switch (vme->u.ipi.mode) {
case APIC_DELMODE_INIT:
- vm_smp_rendezvous(vcpu, vme->u.ipi.dmask, vlapic_handle_init,
+ vm_smp_rendezvous(vcpu, *dmask, vlapic_handle_init,
NULL);
- vm_await_start(vcpu_vm(vcpu), &vme->u.ipi.dmask);
+ vm_await_start(vcpu_vm(vcpu), dmask);
+
+ if (!vlapic->ipi_exit) {
+ *retu = false;
+ }
+
break;
case APIC_DELMODE_STARTUP:
+ /*
+ * Ignore SIPIs in any state other than wait-for-SIPI
+ */
+ *dmask = vm_start_cpus(vcpu_vm(vcpu), dmask);
+
+ if (CPU_EMPTY(dmask)) {
+ *retu = false;
+ break;
+ }
+
+ /*
+ * Old bhyve versions don't support the IPI
+ * exit. Translate it into the old style.
+ */
+ if (!vlapic->ipi_exit) {
+ vme->exitcode = VM_EXITCODE_SPINUP_AP;
+ vme->u.spinup_ap.vcpu = CPU_FFS(dmask);
+ vme->u.spinup_ap.rip = vec << PAGE_SHIFT;
+ }
+
break;
default:
return (1);