diff options
Diffstat (limited to 'arch/x86/include/asm/apic.h')
| -rw-r--r-- | arch/x86/include/asm/apic.h | 66 | 
1 files changed, 52 insertions, 14 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index eaff4790ed96..f34261296ffb 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -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,7 +541,12 @@ static inline const struct cpumask *default_target_cpus(void)  #endif  } -DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); +static inline const struct cpumask *online_target_cpus(void) +{ +	return cpu_online_mask; +} + +DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid);  static inline unsigned int read_apic_id(void) @@ -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)  | 
