]> Pileus Git - ~andy/linux/blobdiff - arch/x86/include/asm/apic.h
Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~andy/linux] / arch / x86 / include / asm / apic.h
index a907d4d251a83baceed25ac6a29689e9c49484ed..f34261296ffb71bc9f62f57ecf069508fe40d9d6 100644 (file)
@@ -306,7 +306,8 @@ struct apic {
        unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid);
        unsigned long (*check_apicid_present)(int apicid);
 
-       void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
+       void (*vector_allocation_domain)(int cpu, struct cpumask *retmask,
+                                        const struct cpumask *mask);
        void (*init_apic_ldr)(void);
 
        void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
@@ -331,9 +332,9 @@ struct apic {
        unsigned long (*set_apic_id)(unsigned int id);
        unsigned long apic_id_mask;
 
-       unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
-       unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
-                                              const struct cpumask *andmask);
+       int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
+                                     const struct cpumask *andmask,
+                                     unsigned int *apicid);
 
        /* ipi */
        void (*send_IPI_mask)(const struct cpumask *mask, int vector);
@@ -464,6 +465,8 @@ static inline u32 safe_apic_wait_icr_idle(void)
        return apic->safe_wait_icr_idle();
 }
 
+extern void __init apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v));
+
 #else /* CONFIG_X86_LOCAL_APIC */
 
 static inline u32 apic_read(u32 reg) { return 0; }
@@ -473,6 +476,7 @@ static inline u64 apic_icr_read(void) { return 0; }
 static inline void apic_icr_write(u32 low, u32 high) { }
 static inline void apic_wait_icr_idle(void) { }
 static inline u32 safe_apic_wait_icr_idle(void) { return 0; }
+static inline void apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v)) {}
 
 #endif /* CONFIG_X86_LOCAL_APIC */
 
@@ -537,6 +541,11 @@ static inline const struct cpumask *default_target_cpus(void)
 #endif
 }
 
+static inline const struct cpumask *online_target_cpus(void)
+{
+       return cpu_online_mask;
+}
+
 DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid);
 
 
@@ -586,21 +595,50 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
 
 #endif
 
-static inline unsigned int
-default_cpu_mask_to_apicid(const struct cpumask *cpumask)
+static inline int
+flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+                           const struct cpumask *andmask,
+                           unsigned int *apicid)
 {
-       return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
+       unsigned long cpu_mask = cpumask_bits(cpumask)[0] &
+                                cpumask_bits(andmask)[0] &
+                                cpumask_bits(cpu_online_mask)[0] &
+                                APIC_ALL_CPUS;
+
+       if (likely(cpu_mask)) {
+               *apicid = (unsigned int)cpu_mask;
+               return 0;
+       } else {
+               return -EINVAL;
+       }
 }
 
-static inline unsigned int
+extern int
 default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-                              const struct cpumask *andmask)
+                              const struct cpumask *andmask,
+                              unsigned int *apicid);
+
+static inline void
+flat_vector_allocation_domain(int cpu, struct cpumask *retmask,
+                             const struct cpumask *mask)
 {
-       unsigned long mask1 = cpumask_bits(cpumask)[0];
-       unsigned long mask2 = cpumask_bits(andmask)[0];
-       unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];
+       /* Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       cpumask_clear(retmask);
+       cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
+}
 
-       return (unsigned int)(mask1 & mask2 & mask3);
+static inline void
+default_vector_allocation_domain(int cpu, struct cpumask *retmask,
+                                const struct cpumask *mask)
+{
+       cpumask_copy(retmask, cpumask_of(cpu));
 }
 
 static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid)