aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Gordeev <agordeev@redhat.com>2012-06-07 09:16:25 -0400
committerIngo Molnar <mingo@kernel.org>2012-06-08 05:44:30 -0400
commit4988a40c3981212fa8c64da68722affc1cb6697a (patch)
tree0210395a3b47a0295ca5015e6ad2d16e1bc58a5e
parentff164324123c0fe181d8de7dadcc7b3fbe25f2cf (diff)
x86/apic: Make cpu_mask_to_apicid() operations check cpu_online_mask
Currently cpu_mask_to_apicid() should not get a offline CPU with the cpumask. Otherwise some apic drivers might try to access non-existent per-cpu variables (i.e. x2apic). In that regard cpu_mask_to_apicid() and cpu_mask_to_apicid_and() operations are inconsistent. This fix makes the two operations do not rely on calling functions and always return the apicid for only online CPUs. As result, the meaning and implementations of cpu_mask_to_apicid() and cpu_mask_to_apicid_and() operations become straight. Signed-off-by: Alexander Gordeev <agordeev@redhat.com> Acked-by: Suresh Siddha <suresh.b.siddha@intel.com> Cc: Yinghai Lu <yinghai@kernel.org> Link: http://lkml.kernel.org/r/20120607131624.GG4759@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/asm/apic.h6
-rw-r--r--arch/x86/kernel/apic/apic.c2
-rw-r--r--arch/x86/kernel/apic/es7000_32.c3
-rw-r--r--arch/x86/kernel/apic/summit_32.c3
-rw-r--r--arch/x86/kernel/apic/x2apic_cluster.c2
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c2
6 files changed, 7 insertions, 11 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index ae91f9c7e36..1ed3eead203 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -596,7 +596,7 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
596static inline int 596static inline int
597__flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid) 597__flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid)
598{ 598{
599 cpu_mask &= APIC_ALL_CPUS; 599 cpu_mask = cpu_mask & APIC_ALL_CPUS & cpumask_bits(cpu_online_mask)[0];
600 if (likely(cpu_mask)) { 600 if (likely(cpu_mask)) {
601 *apicid = (unsigned int)cpu_mask; 601 *apicid = (unsigned int)cpu_mask;
602 return 0; 602 return 0;
@@ -619,9 +619,7 @@ flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
619{ 619{
620 unsigned long mask1 = cpumask_bits(cpumask)[0]; 620 unsigned long mask1 = cpumask_bits(cpumask)[0];
621 unsigned long mask2 = cpumask_bits(andmask)[0]; 621 unsigned long mask2 = cpumask_bits(andmask)[0];
622 unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; 622 return __flat_cpu_mask_to_apicid(mask1 & mask2, apicid);
623
624 return __flat_cpu_mask_to_apicid(mask1 & mask2 & mask3, apicid);
625} 623}
626 624
627extern int 625extern int
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b8d92606f84..7e9bbe73bc5 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2136,7 +2136,7 @@ static inline int __default_cpu_to_apicid(int cpu, unsigned int *apicid)
2136int default_cpu_mask_to_apicid(const struct cpumask *cpumask, 2136int default_cpu_mask_to_apicid(const struct cpumask *cpumask,
2137 unsigned int *apicid) 2137 unsigned int *apicid)
2138{ 2138{
2139 int cpu = cpumask_first(cpumask); 2139 int cpu = cpumask_first_and(cpumask, cpu_online_mask);
2140 return __default_cpu_to_apicid(cpu, apicid); 2140 return __default_cpu_to_apicid(cpu, apicid);
2141} 2141}
2142 2142
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 515ebb00a9f..b35cfb9b696 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -534,7 +534,7 @@ es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
534 /* 534 /*
535 * The cpus in the mask must all be on the apic cluster. 535 * The cpus in the mask must all be on the apic cluster.
536 */ 536 */
537 for_each_cpu(cpu, cpumask) { 537 for_each_cpu_and(cpu, cpumask, cpu_online_mask) {
538 int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); 538 int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
539 539
540 if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { 540 if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
@@ -561,7 +561,6 @@ es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
561 return 0; 561 return 0;
562 562
563 cpumask_and(cpumask, inmask, andmask); 563 cpumask_and(cpumask, inmask, andmask);
564 cpumask_and(cpumask, cpumask, cpu_online_mask);
565 es7000_cpu_mask_to_apicid(cpumask, apicid); 564 es7000_cpu_mask_to_apicid(cpumask, apicid);
566 565
567 free_cpumask_var(cpumask); 566 free_cpumask_var(cpumask);
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
index 5766d84f12d..79d360f6729 100644
--- a/arch/x86/kernel/apic/summit_32.c
+++ b/arch/x86/kernel/apic/summit_32.c
@@ -272,7 +272,7 @@ summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
272 /* 272 /*
273 * The cpus in the mask must all be on the apic cluster. 273 * The cpus in the mask must all be on the apic cluster.
274 */ 274 */
275 for_each_cpu(cpu, cpumask) { 275 for_each_cpu_and(cpu, cpumask, cpu_online_mask) {
276 int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); 276 int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
277 277
278 if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { 278 if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
@@ -298,7 +298,6 @@ summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
298 return 0; 298 return 0;
299 299
300 cpumask_and(cpumask, inmask, andmask); 300 cpumask_and(cpumask, inmask, andmask);
301 cpumask_and(cpumask, cpumask, cpu_online_mask);
302 summit_cpu_mask_to_apicid(cpumask, apicid); 301 summit_cpu_mask_to_apicid(cpumask, apicid);
303 302
304 free_cpumask_var(cpumask); 303 free_cpumask_var(cpumask);
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c
index 5f86f79335f..23a46cf5b6f 100644
--- a/arch/x86/kernel/apic/x2apic_cluster.c
+++ b/arch/x86/kernel/apic/x2apic_cluster.c
@@ -99,7 +99,7 @@ static void x2apic_send_IPI_all(int vector)
99static int 99static int
100x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) 100x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid)
101{ 101{
102 int cpu = cpumask_first(cpumask); 102 int cpu = cpumask_first_and(cpumask, cpu_online_mask);
103 int i; 103 int i;
104 104
105 if (cpu >= nr_cpu_ids) 105 if (cpu >= nr_cpu_ids)
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 2f3030fef31..307aa076bd6 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -286,7 +286,7 @@ uv_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid)
286 * We're using fixed IRQ delivery, can only return one phys APIC ID. 286 * We're using fixed IRQ delivery, can only return one phys APIC ID.
287 * May as well be the first. 287 * May as well be the first.
288 */ 288 */
289 int cpu = cpumask_first(cpumask); 289 int cpu = cpumask_first_and(cpumask, cpu_online_mask);
290 return __uv_cpu_to_apicid(cpu, apicid); 290 return __uv_cpu_to_apicid(cpu, apicid);
291} 291}
292 292