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 @@ -1118,22 +1118,6 @@ break; case APIC_DELMODE_INIT: - if (!vlapic->ipi_exit) { - if (!phys) - break; - - i = vm_apicid2vcpuid(vlapic->vm, dest); - if (i >= vm_get_maxcpus(vlapic->vm) || - i == vlapic->vcpuid) - break; - - CPU_SETOF(i, &ipimask); - - break; - } - - CPU_COPY(&dmask, &ipimask); - break; case APIC_DELMODE_STARTUP: if (!vlapic->ipi_exit) { if (!phys) @@ -1160,7 +1144,7 @@ vmexit->exitcode = VM_EXITCODE_IPI; vmexit->u.ipi.mode = mode; vmexit->u.ipi.vector = vec; - vmexit->u.ipi.dmask = dmask; + vmexit->u.ipi.dmask = ipimask; *retu = true; } @@ -1185,16 +1169,22 @@ *retu = true; switch (vme->u.ipi.mode) { - case APIC_DELMODE_INIT: - vm_smp_rendezvous(vcpu, *dmask, vlapic_handle_init, - NULL); + case APIC_DELMODE_INIT: { + cpuset_t active, reinit; + + active = vm_active_cpus(vcpu_vm(vcpu)); + 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); - if (!vlapic->ipi_exit) { + if (!vlapic->ipi_exit) *retu = false; - } break; + } case APIC_DELMODE_STARTUP: /* * Ignore SIPIs in any state other than wait-for-SIPI @@ -1212,13 +1202,13 @@ */ if (!vlapic->ipi_exit) { vme->exitcode = VM_EXITCODE_SPINUP_AP; - vme->u.spinup_ap.vcpu = CPU_FFS(dmask); + vme->u.spinup_ap.vcpu = CPU_FFS(dmask) - 1; vme->u.spinup_ap.rip = vec << PAGE_SHIFT; } break; default: - return (1); + panic("unexpected delivery mode %#x", vme->u.ipi.mode); } return (0); 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 @@ -1930,10 +1930,8 @@ * VM_EXITCODE_INST_EMUL could access the apic which could transform the * exit code into VM_EXITCODE_IPI. */ - if (error == 0 && vme->exitcode == VM_EXITCODE_IPI) { - retu = false; + if (error == 0 && vme->exitcode == VM_EXITCODE_IPI) error = vm_handle_ipi(vcpu, vme, &retu); - } if (error == 0 && retu == false) goto restart;