void xen_platform_send_ipi(int cpu, int vector, int delivery_mode, int redirect) { #ifdef CONFIG_SMP /* TODO: we need to call vcpu_up here */ if (unlikely(vector == ap_wakeup_vector)) { /* XXX * This should be in __cpu_up(cpu) in ia64 smpboot.c * like x86. But don't want to modify it, * keep it untouched. */ xen_smp_intr_init_early(cpu); xen_send_ipi(cpu, vector); /* vcpu_prepare_and_up(cpu); */ return; } #endif switch (vector) { case IA64_IPI_VECTOR: xen_send_IPI_one(cpu, XEN_IPI_VECTOR); break; case IA64_IPI_RESCHEDULE: xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR); break; case IA64_CMCP_VECTOR: xen_send_IPI_one(cpu, XEN_CMCP_VECTOR); break; case IA64_CPEP_VECTOR: xen_send_IPI_one(cpu, XEN_CPEP_VECTOR); break; case IA64_TIMER_VECTOR: { /* this is used only once by check_sal_cache_flush() at boot time */ static int used = 0; if (!used) { xen_send_ipi(cpu, IA64_TIMER_VECTOR); used = 1; break; } /* fallthrough */ } default: printk(KERN_WARNING "Unsupported IPI type 0x%x\n", vector); notify_remote_via_irq(0); /* defaults to 0 irq */ break; } }
void xen_platform_send_ipi(int cpu, int vector, int delivery_mode, int redirect) { #ifdef CONFIG_SMP /* */ if (unlikely(vector == ap_wakeup_vector)) { /* */ xen_smp_intr_init_early(cpu); xen_send_ipi(cpu, vector); /* */ return; } #endif switch (vector) { case IA64_IPI_VECTOR: xen_send_IPI_one(cpu, XEN_IPI_VECTOR); break; case IA64_IPI_RESCHEDULE: xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR); break; case IA64_CMCP_VECTOR: xen_send_IPI_one(cpu, XEN_CMCP_VECTOR); break; case IA64_CPEP_VECTOR: xen_send_IPI_one(cpu, XEN_CPEP_VECTOR); break; case IA64_TIMER_VECTOR: { /* */ static int used = 0; if (!used) { xen_send_ipi(cpu, IA64_TIMER_VECTOR); used = 1; break; } /* */ } default: printk(KERN_WARNING "Unsupported IPI type 0x%x\n", vector); notify_remote_via_irq(0); /* */ break; } }
/* * Save l's FPU state, which may be on this processor or another processor. * It may take some time, so we avoid disabling preemption where possible. * Caller must know that the target LWP is stopped, otherwise this routine * may race against it. */ void fpusave_lwp(struct lwp *l, bool save) { struct cpu_info *oci; struct pcb *pcb; int s, spins, ticks; spins = 0; ticks = hardclock_ticks; for (;;) { s = splhigh(); pcb = lwp_getpcb(l); oci = pcb->pcb_fpcpu; if (oci == NULL) { splx(s); break; } if (oci == curcpu()) { KASSERT(oci->ci_fpcurlwp == l); fpusave_cpu(save); splx(s); break; } splx(s); #ifdef XEN if (xen_send_ipi(oci, XEN_IPI_SYNCH_FPU) != 0) { panic("xen_send_ipi(%s, XEN_IPI_SYNCH_FPU) failed.", cpu_name(oci)); } #else /* XEN */ x86_send_ipi(oci, X86_IPI_SYNCH_FPU); #endif while (pcb->pcb_fpcpu == oci && ticks == hardclock_ticks) { x86_pause(); spins++; } if (spins > 100000000) { panic("fpusave_lwp: did not"); } } if (!save) { /* Ensure we restart with a clean slate. */ l->l_md.md_flags &= ~MDL_USEDFPU; } }