Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-3.10.git] / arch / x86 / kernel / apic / apic.c
index 0443b64..24deb30 100644 (file)
@@ -2123,6 +2123,42 @@ void default_init_apic_ldr(void)
        apic_write(APIC_LDR, val);
 }
 
+int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+                                  const struct cpumask *andmask,
+                                  unsigned int *apicid)
+{
+       unsigned int cpu;
+
+       for_each_cpu_and(cpu, cpumask, andmask) {
+               if (cpumask_test_cpu(cpu, cpu_online_mask))
+                       break;
+       }
+
+       if (likely(cpu < nr_cpu_ids)) {
+               *apicid = per_cpu(x86_cpu_to_apicid, cpu);
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+/*
+ * Override the generic EOI implementation with an optimized version.
+ * Only called during early boot when only one CPU is active and with
+ * interrupts disabled, so we know this does not race with actual APIC driver
+ * use.
+ */
+void __init apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v))
+{
+       struct apic **drv;
+
+       for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
+               /* Should happen once for each apic */
+               WARN_ON((*drv)->eoi_write == eoi_write);
+               (*drv)->eoi_write = eoi_write;
+       }
+}
+
 /*
  * Power management
  */