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 @@ -686,6 +686,11 @@ struct vm_guest_paging paging; }; +#define IPI_CPUSETSIZE 256 + +__BITSET_DEFINE(_ipi_cpuset, IPI_CPUSETSIZE); +typedef struct _ipi_cpuset ipi_cpuset_t; + struct vm_exit { enum vm_exitcode exitcode; int inst_length; /* 0 means unknown */ @@ -756,7 +761,7 @@ struct { uint32_t mode; uint8_t vector; - cpuset_t dmask; + ipi_cpuset_t dmask; } ipi; struct vm_task_switch task_switch; } u; diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c --- a/sys/amd64/vmm/io/vlapic.c +++ b/sys/amd64/vmm/io/vlapic.c @@ -1146,7 +1146,10 @@ vmexit->exitcode = VM_EXITCODE_IPI; vmexit->u.ipi.mode = mode; vmexit->u.ipi.vector = vec; - vmexit->u.ipi.dmask = ipimask; + __BIT_ZERO(IPI_CPUSETSIZE, &vmexit->u.ipi.dmask); + memcpy(&vmexit->u.ipi.dmask, &ipimask, + __bitset_words(min(CPU_SETSIZE, IPI_CPUSETSIZE)) * + (_BITSET_BITS / 8)); *retu = true; } @@ -1166,21 +1169,26 @@ 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; + cpuset_t dmask; uint8_t vec = vme->u.ipi.vector; + CPU_ZERO(&dmask); + memcpy(&dmask, &vme->u.ipi.dmask, + __bitset_words(min(CPU_SETSIZE, IPI_CPUSETSIZE)) * + (_BITSET_BITS / 8)); + *retu = true; switch (vme->u.ipi.mode) { case APIC_DELMODE_INIT: { cpuset_t active, reinit; active = vm_active_cpus(vcpu_vm(vcpu)); - CPU_AND(&reinit, &active, dmask); + CPU_AND(&reinit, &active, &dmask); if (!CPU_EMPTY(&reinit)) { vm_smp_rendezvous(vcpu, reinit, vlapic_handle_init, NULL); } - vm_await_start(vcpu_vm(vcpu), dmask); + vm_await_start(vcpu_vm(vcpu), &dmask); if (!vlapic->ipi_exit) *retu = false; @@ -1191,9 +1199,9 @@ /* * Ignore SIPIs in any state other than wait-for-SIPI */ - *dmask = vm_start_cpus(vcpu_vm(vcpu), dmask); + dmask = vm_start_cpus(vcpu_vm(vcpu), &dmask); - if (CPU_EMPTY(dmask)) { + if (CPU_EMPTY(&dmask)) { *retu = false; break; } @@ -1204,7 +1212,7 @@ */ if (!vlapic->ipi_exit) { vme->exitcode = VM_EXITCODE_SPINUP_AP; - vme->u.spinup_ap.vcpu = CPU_FFS(dmask) - 1; + vme->u.spinup_ap.vcpu = CPU_FFS(&dmask) - 1; vme->u.spinup_ap.rip = vec << PAGE_SHIFT; } diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -929,7 +929,7 @@ int i; switch (vme->u.ipi.mode) { case APIC_DELMODE_INIT: - CPU_FOREACH_ISSET(i, &vme->u.ipi.dmask) { + __BIT_FOREACH_ISSET(IPI_CPUSETSIZE, i, &vme->u.ipi.dmask) { error = vm_suspend_cpu(vcpu_info[i].vcpu); if (error) { warnx("%s: failed to suspend cpu %d\n", @@ -939,7 +939,7 @@ } break; case APIC_DELMODE_STARTUP: - CPU_FOREACH_ISSET(i, &vme->u.ipi.dmask) { + __BIT_FOREACH_ISSET(IPI_CPUSETSIZE, i, &vme->u.ipi.dmask) { spinup_ap(vcpu_info[i].vcpu, vme->u.ipi.vector << PAGE_SHIFT); }