static void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector) { unsigned int cpu; unsigned long flags; uint64_t msr_content; /* * Ensure that any synchronisation data written in program order by this * CPU is seen by notified remote CPUs. The WRMSR contained within * apic_icr_write() can otherwise be executed early. * * The reason mb() is sufficient here is subtle: the register arguments * to WRMSR must depend on a memory read executed after the barrier. This * is guaranteed by cpu_physical_id(), which reads from a global array (and * so cannot be hoisted above the barrier even by a clever compiler). */ mb(); local_irq_save(flags); for_each_cpu ( cpu, cpumask ) { if ( !cpu_online(cpu) || (cpu == smp_processor_id()) ) continue; msr_content = cpu_physical_id(cpu); msr_content = (msr_content << 32) | APIC_DM_FIXED | APIC_DEST_PHYSICAL | vector; apic_wrmsr(APIC_ICR, msr_content); } local_irq_restore(flags); }
static void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector) { unsigned int cpu = smp_processor_id(); cpumask_t *ipimask = per_cpu(scratch_mask, cpu); const cpumask_t *cluster_cpus; unsigned long flags; mb(); /* See above for an explanation. */ local_irq_save(flags); cpumask_andnot(ipimask, &cpu_online_map, cpumask_of(cpu)); for ( cpumask_and(ipimask, cpumask, ipimask); !cpumask_empty(ipimask); cpumask_andnot(ipimask, ipimask, cluster_cpus) ) { uint64_t msr_content = 0; cluster_cpus = per_cpu(cluster_cpus, cpumask_first(ipimask)); for_each_cpu ( cpu, cluster_cpus ) { if ( !cpumask_test_cpu(cpu, ipimask) ) continue; msr_content |= per_cpu(cpu_2_logical_apicid, cpu); } BUG_ON(!msr_content); msr_content = (msr_content << 32) | APIC_DM_FIXED | APIC_DEST_LOGICAL | vector; apic_wrmsr(APIC_ICR, msr_content); } local_irq_restore(flags); }
void send_IPI_mask_x2apic(const cpumask_t *cpumask, int vector) { unsigned int cpu, cfg; unsigned long flags; /* * Ensure that any synchronisation data written in program order by this * CPU is seen by notified remote CPUs. The WRMSR contained within * apic_icr_write() can otherwise be executed early. * * The reason mb() is sufficient here is subtle: the register arguments * to WRMSR must depend on a memory read executed after the barrier. This * is guaranteed by cpu_physical_id(), which reads from a global array (and * so cannot be hoisted above the barrier even by a clever compiler). */ mb(); local_irq_save(flags); cfg = APIC_DM_FIXED | 0 /* no shorthand */ | APIC_DEST_PHYSICAL | vector; for_each_cpu_mask ( cpu, *cpumask ) if ( cpu != smp_processor_id() ) apic_wrmsr(APIC_ICR, cfg, cpu_physical_id(cpu)); local_irq_restore(flags); }
static void send_IPI_self_x2apic(uint8_t vector) { apic_wrmsr(APIC_SELF_IPI, vector); }