Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ia64: Validate online cpus in irq_set_affinity() callbacks

The [user space] interface does not filter out offline cpus. It merily
guarantees that the mask contains at least one online cpu.

So the selector in the irq chip implementation needs to make sure to
pick only an online cpu because otherwise:

Offline Core 1
Set affinity to 0xe (is valid due to online mask 0xd)
cpumask_first will pick core 1, which is offline

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: ia64 <linux-ia64@vger.kernel.org>
Link: http://lkml.kernel.org/r/20140304203100.650414633@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

+5 -11
+2 -8
arch/ia64/kernel/msi_ia64.c
··· 17 17 { 18 18 struct msi_msg msg; 19 19 u32 addr, data; 20 - int cpu = first_cpu(*cpu_mask); 20 + int cpu = cpumask_first_and(cpu_mask, cpu_online_mask); 21 21 unsigned int irq = idata->irq; 22 - 23 - if (!cpu_online(cpu)) 24 - return -1; 25 22 26 23 if (irq_prepare_move(irq, cpu)) 27 24 return -1; ··· 136 139 unsigned int irq = data->irq; 137 140 struct irq_cfg *cfg = irq_cfg + irq; 138 141 struct msi_msg msg; 139 - int cpu = cpumask_first(mask); 140 - 141 - if (!cpu_online(cpu)) 142 - return -1; 142 + int cpu = cpumask_first_and(mask, cpu_online_mask); 143 143 144 144 if (irq_prepare_move(irq, cpu)) 145 145 return -1;
+2 -2
arch/ia64/sn/kernel/irq.c
··· 209 209 nasid_t nasid; 210 210 int slice; 211 211 212 - nasid = cpuid_to_nasid(cpumask_first(mask)); 213 - slice = cpuid_to_slice(cpumask_first(mask)); 212 + nasid = cpuid_to_nasid(cpumask_first_and(mask, cpu_online_mask)); 213 + slice = cpuid_to_slice(cpumask_first_and(mask, cpu_online_mask)); 214 214 215 215 list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, 216 216 sn_irq_lh[irq], list)
+1 -1
arch/ia64/sn/kernel/msi_sn.c
··· 166 166 struct sn_pcibus_provider *provider; 167 167 unsigned int cpu, irq = data->irq; 168 168 169 - cpu = cpumask_first(cpu_mask); 169 + cpu = cpumask_first_and(cpu_mask, cpu_online_mask); 170 170 sn_irq_info = sn_msi_info[irq].sn_irq_info; 171 171 if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) 172 172 return -1;