void ipi_process(struct cpu_info *ci, uint64_t ipi_mask) { KASSERT(cpu_intr_p()); if (ipi_mask & __BIT(IPI_NOP)) { ci->ci_evcnt_per_ipi[IPI_NOP].ev_count++; ipi_nop(ci); } if (ipi_mask & __BIT(IPI_AST)) { ci->ci_evcnt_per_ipi[IPI_AST].ev_count++; ipi_nop(ci); } if (ipi_mask & __BIT(IPI_SHOOTDOWN)) { ci->ci_evcnt_per_ipi[IPI_SHOOTDOWN].ev_count++; ipi_shootdown(ci); } if (ipi_mask & __BIT(IPI_SYNCICACHE)) { ci->ci_evcnt_per_ipi[IPI_SYNCICACHE].ev_count++; ipi_syncicache(ci); } if (ipi_mask & __BIT(IPI_SUSPEND)) { ci->ci_evcnt_per_ipi[IPI_SUSPEND].ev_count++; cpu_pause(NULL); } if (ipi_mask & __BIT(IPI_HALT)) { ci->ci_evcnt_per_ipi[IPI_HALT].ev_count++; ipi_halt(); } if (ipi_mask & __BIT(IPI_XCALL)) { ci->ci_evcnt_per_ipi[IPI_XCALL].ev_count++; xc_ipi_handler(); } if (ipi_mask & __BIT(IPI_GENERIC)) { ci->ci_evcnt_per_ipi[IPI_GENERIC].ev_count++; ipi_cpu_handler(); } }
int ipi_intr(void *v) { struct cpu_info * const ci = curcpu(); int cpu_id = cpu_index(ci); int msr; uint32_t ipi; ci->ci_ev_ipi.ev_count++; ipi = atomic_swap_32(&ci->ci_pending_ipis, 0); if (ipi == IPI_NOMESG) return 1; if (ipi & IPI_XCALL) xc_ipi_handler(); if (ipi & IPI_GENERIC) ipi_cpu_handler(); if (ipi & IPI_SUSPEND) cpu_pause(NULL); if (ipi & IPI_HALT) { struct cpuset_info * const csi = &cpuset_info; aprint_normal("halting CPU %d\n", cpu_id); kcpuset_set(csi->cpus_halted, cpu_id); msr = (mfmsr() & ~PSL_EE) | PSL_POW; for (;;) { __asm volatile ("sync; isync"); mtmsr(msr); } } return 1; }