diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/apic.h | 44 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 33 | ||||
-rw-r--r-- | arch/x86/kernel/apic/es7000_32.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 88 | ||||
-rw-r--r-- | arch/x86/kernel/apic/numaq_32.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/apic/summit_32.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 27 | ||||
-rw-r--r-- | arch/x86/platform/uv/uv_irq.c | 7 |
9 files changed, 178 insertions, 102 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index e3fecd50d5ca..ae91f9c7e360 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
@@ -331,9 +331,11 @@ struct apic { | |||
331 | unsigned long (*set_apic_id)(unsigned int id); | 331 | unsigned long (*set_apic_id)(unsigned int id); |
332 | unsigned long apic_id_mask; | 332 | unsigned long apic_id_mask; |
333 | 333 | ||
334 | unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask); | 334 | int (*cpu_mask_to_apicid)(const struct cpumask *cpumask, |
335 | unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, | 335 | unsigned int *apicid); |
336 | const struct cpumask *andmask); | 336 | int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, |
337 | const struct cpumask *andmask, | ||
338 | unsigned int *apicid); | ||
337 | 339 | ||
338 | /* ipi */ | 340 | /* ipi */ |
339 | void (*send_IPI_mask)(const struct cpumask *mask, int vector); | 341 | void (*send_IPI_mask)(const struct cpumask *mask, int vector); |
@@ -591,29 +593,45 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) | |||
591 | 593 | ||
592 | #endif | 594 | #endif |
593 | 595 | ||
594 | static inline unsigned int | 596 | static inline int |
595 | flat_cpu_mask_to_apicid(const struct cpumask *cpumask) | 597 | __flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid) |
596 | { | 598 | { |
597 | return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; | 599 | cpu_mask &= APIC_ALL_CPUS; |
600 | if (likely(cpu_mask)) { | ||
601 | *apicid = (unsigned int)cpu_mask; | ||
602 | return 0; | ||
603 | } else { | ||
604 | return -EINVAL; | ||
605 | } | ||
598 | } | 606 | } |
599 | 607 | ||
600 | static inline unsigned int | 608 | static inline int |
609 | flat_cpu_mask_to_apicid(const struct cpumask *cpumask, | ||
610 | unsigned int *apicid) | ||
611 | { | ||
612 | return __flat_cpu_mask_to_apicid(cpumask_bits(cpumask)[0], apicid); | ||
613 | } | ||
614 | |||
615 | static inline int | ||
601 | flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 616 | flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
602 | const struct cpumask *andmask) | 617 | const struct cpumask *andmask, |
618 | unsigned int *apicid) | ||
603 | { | 619 | { |
604 | unsigned long mask1 = cpumask_bits(cpumask)[0]; | 620 | unsigned long mask1 = cpumask_bits(cpumask)[0]; |
605 | unsigned long mask2 = cpumask_bits(andmask)[0]; | 621 | unsigned long mask2 = cpumask_bits(andmask)[0]; |
606 | unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; | 622 | unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; |
607 | 623 | ||
608 | return (unsigned int)(mask1 & mask2 & mask3); | 624 | return __flat_cpu_mask_to_apicid(mask1 & mask2 & mask3, apicid); |
609 | } | 625 | } |
610 | 626 | ||
611 | extern unsigned int | 627 | extern int |
612 | default_cpu_mask_to_apicid(const struct cpumask *cpumask); | 628 | default_cpu_mask_to_apicid(const struct cpumask *cpumask, |
629 | unsigned int *apicid); | ||
613 | 630 | ||
614 | extern unsigned int | 631 | extern int |
615 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 632 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
616 | const struct cpumask *andmask); | 633 | const struct cpumask *andmask, |
634 | unsigned int *apicid); | ||
617 | 635 | ||
618 | static inline bool | 636 | static inline bool |
619 | flat_vector_allocation_domain(int cpu, struct cpumask *retmask) | 637 | flat_vector_allocation_domain(int cpu, struct cpumask *retmask) |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 96a2608252f1..b8d92606f84f 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -2123,24 +2123,26 @@ void default_init_apic_ldr(void) | |||
2123 | apic_write(APIC_LDR, val); | 2123 | apic_write(APIC_LDR, val); |
2124 | } | 2124 | } |
2125 | 2125 | ||
2126 | unsigned int default_cpu_mask_to_apicid(const struct cpumask *cpumask) | 2126 | static inline int __default_cpu_to_apicid(int cpu, unsigned int *apicid) |
2127 | { | 2127 | { |
2128 | int cpu; | 2128 | if (likely((unsigned int)cpu < nr_cpu_ids)) { |
2129 | 2129 | *apicid = per_cpu(x86_cpu_to_apicid, cpu); | |
2130 | /* | 2130 | return 0; |
2131 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | 2131 | } else { |
2132 | * May as well be the first. | 2132 | return -EINVAL; |
2133 | */ | 2133 | } |
2134 | cpu = cpumask_first(cpumask); | 2134 | } |
2135 | if (likely((unsigned)cpu < nr_cpu_ids)) | ||
2136 | return per_cpu(x86_cpu_to_apicid, cpu); | ||
2137 | 2135 | ||
2138 | return BAD_APICID; | 2136 | int default_cpu_mask_to_apicid(const struct cpumask *cpumask, |
2137 | unsigned int *apicid) | ||
2138 | { | ||
2139 | int cpu = cpumask_first(cpumask); | ||
2140 | return __default_cpu_to_apicid(cpu, apicid); | ||
2139 | } | 2141 | } |
2140 | 2142 | ||
2141 | unsigned int | 2143 | int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
2142 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 2144 | const struct cpumask *andmask, |
2143 | const struct cpumask *andmask) | 2145 | unsigned int *apicid) |
2144 | { | 2146 | { |
2145 | int cpu; | 2147 | int cpu; |
2146 | 2148 | ||
@@ -2148,7 +2150,8 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | |||
2148 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | 2150 | if (cpumask_test_cpu(cpu, cpu_online_mask)) |
2149 | break; | 2151 | break; |
2150 | } | 2152 | } |
2151 | return per_cpu(x86_cpu_to_apicid, cpu); | 2153 | |
2154 | return __default_cpu_to_apicid(cpu, apicid); | ||
2152 | } | 2155 | } |
2153 | 2156 | ||
2154 | /* | 2157 | /* |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 3c42865757e2..515ebb00a9fc 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -525,7 +525,8 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid) | |||
525 | return 1; | 525 | return 1; |
526 | } | 526 | } |
527 | 527 | ||
528 | static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask) | 528 | static int |
529 | es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) | ||
529 | { | 530 | { |
530 | unsigned int round = 0; | 531 | unsigned int round = 0; |
531 | int cpu, uninitialized_var(apicid); | 532 | int cpu, uninitialized_var(apicid); |
@@ -539,31 +540,33 @@ static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask) | |||
539 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | 540 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { |
540 | WARN(1, "Not a valid mask!"); | 541 | WARN(1, "Not a valid mask!"); |
541 | 542 | ||
542 | return BAD_APICID; | 543 | return -EINVAL; |
543 | } | 544 | } |
544 | apicid = new_apicid; | 545 | apicid = new_apicid; |
545 | round++; | 546 | round++; |
546 | } | 547 | } |
547 | return apicid; | 548 | *dest_id = apicid; |
549 | return 0; | ||
548 | } | 550 | } |
549 | 551 | ||
550 | static unsigned int | 552 | static int |
551 | es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, | 553 | es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, |
552 | const struct cpumask *andmask) | 554 | const struct cpumask *andmask, |
555 | unsigned int *apicid) | ||
553 | { | 556 | { |
554 | int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); | 557 | *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); |
555 | cpumask_var_t cpumask; | 558 | cpumask_var_t cpumask; |
556 | 559 | ||
557 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) | 560 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) |
558 | return apicid; | 561 | return 0; |
559 | 562 | ||
560 | cpumask_and(cpumask, inmask, andmask); | 563 | cpumask_and(cpumask, inmask, andmask); |
561 | cpumask_and(cpumask, cpumask, cpu_online_mask); | 564 | cpumask_and(cpumask, cpumask, cpu_online_mask); |
562 | apicid = es7000_cpu_mask_to_apicid(cpumask); | 565 | es7000_cpu_mask_to_apicid(cpumask, apicid); |
563 | 566 | ||
564 | free_cpumask_var(cpumask); | 567 | free_cpumask_var(cpumask); |
565 | 568 | ||
566 | return apicid; | 569 | return 0; |
567 | } | 570 | } |
568 | 571 | ||
569 | static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) | 572 | static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 4061a7dee5c9..0deb773404e5 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1359,7 +1359,14 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, | |||
1359 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) | 1359 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) |
1360 | return; | 1360 | return; |
1361 | 1361 | ||
1362 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 1362 | if (apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus(), |
1363 | &dest)) { | ||
1364 | pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n", | ||
1365 | mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); | ||
1366 | __clear_irq_vector(irq, cfg); | ||
1367 | |||
1368 | return; | ||
1369 | } | ||
1363 | 1370 | ||
1364 | apic_printk(APIC_VERBOSE,KERN_DEBUG | 1371 | apic_printk(APIC_VERBOSE,KERN_DEBUG |
1365 | "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " | 1372 | "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " |
@@ -1474,6 +1481,7 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, | |||
1474 | unsigned int pin, int vector) | 1481 | unsigned int pin, int vector) |
1475 | { | 1482 | { |
1476 | struct IO_APIC_route_entry entry; | 1483 | struct IO_APIC_route_entry entry; |
1484 | unsigned int dest; | ||
1477 | 1485 | ||
1478 | if (irq_remapping_enabled) | 1486 | if (irq_remapping_enabled) |
1479 | return; | 1487 | return; |
@@ -1484,9 +1492,12 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, | |||
1484 | * We use logical delivery to get the timer IRQ | 1492 | * We use logical delivery to get the timer IRQ |
1485 | * to the first CPU. | 1493 | * to the first CPU. |
1486 | */ | 1494 | */ |
1495 | if (unlikely(apic->cpu_mask_to_apicid(apic->target_cpus(), &dest))) | ||
1496 | dest = BAD_APICID; | ||
1497 | |||
1487 | entry.dest_mode = apic->irq_dest_mode; | 1498 | entry.dest_mode = apic->irq_dest_mode; |
1488 | entry.mask = 0; /* don't mask IRQ for edge */ | 1499 | entry.mask = 0; /* don't mask IRQ for edge */ |
1489 | entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus()); | 1500 | entry.dest = dest; |
1490 | entry.delivery_mode = apic->irq_delivery_mode; | 1501 | entry.delivery_mode = apic->irq_delivery_mode; |
1491 | entry.polarity = 0; | 1502 | entry.polarity = 0; |
1492 | entry.trigger = 0; | 1503 | entry.trigger = 0; |
@@ -2245,16 +2256,25 @@ int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
2245 | unsigned int *dest_id) | 2256 | unsigned int *dest_id) |
2246 | { | 2257 | { |
2247 | struct irq_cfg *cfg = data->chip_data; | 2258 | struct irq_cfg *cfg = data->chip_data; |
2259 | unsigned int irq = data->irq; | ||
2260 | int err; | ||
2248 | 2261 | ||
2249 | if (!cpumask_intersects(mask, cpu_online_mask)) | 2262 | if (!cpumask_intersects(mask, cpu_online_mask)) |
2250 | return -1; | 2263 | return -EINVAL; |
2251 | 2264 | ||
2252 | if (assign_irq_vector(data->irq, data->chip_data, mask)) | 2265 | err = assign_irq_vector(irq, cfg, mask); |
2253 | return -1; | 2266 | if (err) |
2267 | return err; | ||
2268 | |||
2269 | err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id); | ||
2270 | if (err) { | ||
2271 | if (assign_irq_vector(irq, cfg, data->affinity)) | ||
2272 | pr_err("Failed to recover vector for irq %d\n", irq); | ||
2273 | return err; | ||
2274 | } | ||
2254 | 2275 | ||
2255 | cpumask_copy(data->affinity, mask); | 2276 | cpumask_copy(data->affinity, mask); |
2256 | 2277 | ||
2257 | *dest_id = apic->cpu_mask_to_apicid_and(mask, cfg->domain); | ||
2258 | return 0; | 2278 | return 0; |
2259 | } | 2279 | } |
2260 | 2280 | ||
@@ -3040,7 +3060,10 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, | |||
3040 | if (err) | 3060 | if (err) |
3041 | return err; | 3061 | return err; |
3042 | 3062 | ||
3043 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 3063 | err = apic->cpu_mask_to_apicid_and(cfg->domain, |
3064 | apic->target_cpus(), &dest); | ||
3065 | if (err) | ||
3066 | return err; | ||
3044 | 3067 | ||
3045 | if (irq_remapped(cfg)) { | 3068 | if (irq_remapped(cfg)) { |
3046 | compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); | 3069 | compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); |
@@ -3361,6 +3384,8 @@ static struct irq_chip ht_irq_chip = { | |||
3361 | int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | 3384 | int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) |
3362 | { | 3385 | { |
3363 | struct irq_cfg *cfg; | 3386 | struct irq_cfg *cfg; |
3387 | struct ht_irq_msg msg; | ||
3388 | unsigned dest; | ||
3364 | int err; | 3389 | int err; |
3365 | 3390 | ||
3366 | if (disable_apic) | 3391 | if (disable_apic) |
@@ -3368,36 +3393,37 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
3368 | 3393 | ||
3369 | cfg = irq_cfg(irq); | 3394 | cfg = irq_cfg(irq); |
3370 | err = assign_irq_vector(irq, cfg, apic->target_cpus()); | 3395 | err = assign_irq_vector(irq, cfg, apic->target_cpus()); |
3371 | if (!err) { | 3396 | if (err) |
3372 | struct ht_irq_msg msg; | 3397 | return err; |
3373 | unsigned dest; | ||
3374 | 3398 | ||
3375 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, | 3399 | err = apic->cpu_mask_to_apicid_and(cfg->domain, |
3376 | apic->target_cpus()); | 3400 | apic->target_cpus(), &dest); |
3401 | if (err) | ||
3402 | return err; | ||
3377 | 3403 | ||
3378 | msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); | 3404 | msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); |
3379 | 3405 | ||
3380 | msg.address_lo = | 3406 | msg.address_lo = |
3381 | HT_IRQ_LOW_BASE | | 3407 | HT_IRQ_LOW_BASE | |
3382 | HT_IRQ_LOW_DEST_ID(dest) | | 3408 | HT_IRQ_LOW_DEST_ID(dest) | |
3383 | HT_IRQ_LOW_VECTOR(cfg->vector) | | 3409 | HT_IRQ_LOW_VECTOR(cfg->vector) | |
3384 | ((apic->irq_dest_mode == 0) ? | 3410 | ((apic->irq_dest_mode == 0) ? |
3385 | HT_IRQ_LOW_DM_PHYSICAL : | 3411 | HT_IRQ_LOW_DM_PHYSICAL : |
3386 | HT_IRQ_LOW_DM_LOGICAL) | | 3412 | HT_IRQ_LOW_DM_LOGICAL) | |
3387 | HT_IRQ_LOW_RQEOI_EDGE | | 3413 | HT_IRQ_LOW_RQEOI_EDGE | |
3388 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | 3414 | ((apic->irq_delivery_mode != dest_LowestPrio) ? |
3389 | HT_IRQ_LOW_MT_FIXED : | 3415 | HT_IRQ_LOW_MT_FIXED : |
3390 | HT_IRQ_LOW_MT_ARBITRATED) | | 3416 | HT_IRQ_LOW_MT_ARBITRATED) | |
3391 | HT_IRQ_LOW_IRQ_MASKED; | 3417 | HT_IRQ_LOW_IRQ_MASKED; |
3392 | 3418 | ||
3393 | write_ht_irq_msg(irq, &msg); | 3419 | write_ht_irq_msg(irq, &msg); |
3394 | 3420 | ||
3395 | irq_set_chip_and_handler_name(irq, &ht_irq_chip, | 3421 | irq_set_chip_and_handler_name(irq, &ht_irq_chip, |
3396 | handle_edge_irq, "edge"); | 3422 | handle_edge_irq, "edge"); |
3397 | 3423 | ||
3398 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); | 3424 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); |
3399 | } | 3425 | |
3400 | return err; | 3426 | return 0; |
3401 | } | 3427 | } |
3402 | #endif /* CONFIG_HT_IRQ */ | 3428 | #endif /* CONFIG_HT_IRQ */ |
3403 | 3429 | ||
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index eb2d466fd81a..2b55514c328b 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c | |||
@@ -406,16 +406,20 @@ static inline int numaq_check_phys_apicid_present(int phys_apicid) | |||
406 | * We use physical apicids here, not logical, so just return the default | 406 | * We use physical apicids here, not logical, so just return the default |
407 | * physical broadcast to stop people from breaking us | 407 | * physical broadcast to stop people from breaking us |
408 | */ | 408 | */ |
409 | static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask) | 409 | static int |
410 | numaq_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) | ||
410 | { | 411 | { |
411 | return 0x0F; | 412 | *apicid = 0x0F; |
413 | return 0; | ||
412 | } | 414 | } |
413 | 415 | ||
414 | static inline unsigned int | 416 | static int |
415 | numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 417 | numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
416 | const struct cpumask *andmask) | 418 | const struct cpumask *andmask, |
419 | unsigned int *apicid) | ||
417 | { | 420 | { |
418 | return 0x0F; | 421 | *apicid = 0x0F; |
422 | return 0; | ||
419 | } | 423 | } |
420 | 424 | ||
421 | /* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ | 425 | /* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ |
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 35d254c1fec2..5766d84f12d6 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -263,7 +263,8 @@ static int summit_check_phys_apicid_present(int physical_apicid) | |||
263 | return 1; | 263 | return 1; |
264 | } | 264 | } |
265 | 265 | ||
266 | static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) | 266 | static int |
267 | summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) | ||
267 | { | 268 | { |
268 | unsigned int round = 0; | 269 | unsigned int round = 0; |
269 | int cpu, apicid = 0; | 270 | int cpu, apicid = 0; |
@@ -276,30 +277,33 @@ static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) | |||
276 | 277 | ||
277 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | 278 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { |
278 | printk("%s: Not a valid mask!\n", __func__); | 279 | printk("%s: Not a valid mask!\n", __func__); |
279 | return BAD_APICID; | 280 | return -EINVAL; |
280 | } | 281 | } |
281 | apicid |= new_apicid; | 282 | apicid |= new_apicid; |
282 | round++; | 283 | round++; |
283 | } | 284 | } |
284 | return apicid; | 285 | *dest_id = apicid; |
286 | return 0; | ||
285 | } | 287 | } |
286 | 288 | ||
287 | static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, | 289 | static int |
288 | const struct cpumask *andmask) | 290 | summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, |
291 | const struct cpumask *andmask, | ||
292 | unsigned int *apicid) | ||
289 | { | 293 | { |
290 | int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); | 294 | *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); |
291 | cpumask_var_t cpumask; | 295 | cpumask_var_t cpumask; |
292 | 296 | ||
293 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) | 297 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) |
294 | return apicid; | 298 | return 0; |
295 | 299 | ||
296 | cpumask_and(cpumask, inmask, andmask); | 300 | cpumask_and(cpumask, inmask, andmask); |
297 | cpumask_and(cpumask, cpumask, cpu_online_mask); | 301 | cpumask_and(cpumask, cpumask, cpu_online_mask); |
298 | apicid = summit_cpu_mask_to_apicid(cpumask); | 302 | summit_cpu_mask_to_apicid(cpumask, apicid); |
299 | 303 | ||
300 | free_cpumask_var(cpumask); | 304 | free_cpumask_var(cpumask); |
301 | 305 | ||
302 | return apicid; | 306 | return 0; |
303 | } | 307 | } |
304 | 308 | ||
305 | /* | 309 | /* |
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 612622c47dfb..5f86f79335f4 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
@@ -96,24 +96,26 @@ static void x2apic_send_IPI_all(int vector) | |||
96 | __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); | 96 | __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); |
97 | } | 97 | } |
98 | 98 | ||
99 | static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) | 99 | static int |
100 | x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) | ||
100 | { | 101 | { |
101 | int cpu = cpumask_first(cpumask); | 102 | int cpu = cpumask_first(cpumask); |
102 | u32 dest = 0; | ||
103 | int i; | 103 | int i; |
104 | 104 | ||
105 | if (cpu > nr_cpu_ids) | 105 | if (cpu >= nr_cpu_ids) |
106 | return BAD_APICID; | 106 | return -EINVAL; |
107 | 107 | ||
108 | *apicid = 0; | ||
108 | for_each_cpu_and(i, cpumask, per_cpu(cpus_in_cluster, cpu)) | 109 | for_each_cpu_and(i, cpumask, per_cpu(cpus_in_cluster, cpu)) |
109 | dest |= per_cpu(x86_cpu_to_logical_apicid, i); | 110 | *apicid |= per_cpu(x86_cpu_to_logical_apicid, i); |
110 | 111 | ||
111 | return dest; | 112 | return 0; |
112 | } | 113 | } |
113 | 114 | ||
114 | static unsigned int | 115 | static int |
115 | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 116 | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
116 | const struct cpumask *andmask) | 117 | const struct cpumask *andmask, |
118 | unsigned int *apicid) | ||
117 | { | 119 | { |
118 | u32 dest = 0; | 120 | u32 dest = 0; |
119 | u16 cluster; | 121 | u16 cluster; |
@@ -128,7 +130,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | |||
128 | } | 130 | } |
129 | 131 | ||
130 | if (!dest) | 132 | if (!dest) |
131 | return BAD_APICID; | 133 | return -EINVAL; |
132 | 134 | ||
133 | for_each_cpu_and(i, cpumask, andmask) { | 135 | for_each_cpu_and(i, cpumask, andmask) { |
134 | if (!cpumask_test_cpu(i, cpu_online_mask)) | 136 | if (!cpumask_test_cpu(i, cpu_online_mask)) |
@@ -138,7 +140,9 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | |||
138 | dest |= per_cpu(x86_cpu_to_logical_apicid, i); | 140 | dest |= per_cpu(x86_cpu_to_logical_apicid, i); |
139 | } | 141 | } |
140 | 142 | ||
141 | return dest; | 143 | *apicid = dest; |
144 | |||
145 | return 0; | ||
142 | } | 146 | } |
143 | 147 | ||
144 | static void init_x2apic_ldr(void) | 148 | static void init_x2apic_ldr(void) |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index df89a7d78748..2f3030fef31e 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -269,23 +269,31 @@ static void uv_init_apic_ldr(void) | |||
269 | { | 269 | { |
270 | } | 270 | } |
271 | 271 | ||
272 | static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask) | 272 | static inline int __uv_cpu_to_apicid(int cpu, unsigned int *apicid) |
273 | { | ||
274 | if (likely((unsigned int)cpu < nr_cpu_ids)) { | ||
275 | *apicid = per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; | ||
276 | return 0; | ||
277 | } else { | ||
278 | return -EINVAL; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static int | ||
283 | uv_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) | ||
273 | { | 284 | { |
274 | /* | 285 | /* |
275 | * 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. |
276 | * May as well be the first. | 287 | * May as well be the first. |
277 | */ | 288 | */ |
278 | int cpu = cpumask_first(cpumask); | 289 | int cpu = cpumask_first(cpumask); |
279 | 290 | return __uv_cpu_to_apicid(cpu, apicid); | |
280 | if ((unsigned)cpu < nr_cpu_ids) | ||
281 | return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; | ||
282 | else | ||
283 | return BAD_APICID; | ||
284 | } | 291 | } |
285 | 292 | ||
286 | static unsigned int | 293 | static int |
287 | uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 294 | uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
288 | const struct cpumask *andmask) | 295 | const struct cpumask *andmask, |
296 | unsigned int *apicid) | ||
289 | { | 297 | { |
290 | int cpu; | 298 | int cpu; |
291 | 299 | ||
@@ -297,7 +305,8 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | |||
297 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | 305 | if (cpumask_test_cpu(cpu, cpu_online_mask)) |
298 | break; | 306 | break; |
299 | } | 307 | } |
300 | return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; | 308 | |
309 | return __uv_cpu_to_apicid(cpu, apicid); | ||
301 | } | 310 | } |
302 | 311 | ||
303 | static unsigned int x2apic_get_apic_id(unsigned long x) | 312 | static unsigned int x2apic_get_apic_id(unsigned long x) |
diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c index f25c2765a5c9..dd1ff39a464c 100644 --- a/arch/x86/platform/uv/uv_irq.c +++ b/arch/x86/platform/uv/uv_irq.c | |||
@@ -135,6 +135,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
135 | unsigned long mmr_value; | 135 | unsigned long mmr_value; |
136 | struct uv_IO_APIC_route_entry *entry; | 136 | struct uv_IO_APIC_route_entry *entry; |
137 | int mmr_pnode, err; | 137 | int mmr_pnode, err; |
138 | unsigned int dest; | ||
138 | 139 | ||
139 | BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != | 140 | BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != |
140 | sizeof(unsigned long)); | 141 | sizeof(unsigned long)); |
@@ -143,6 +144,10 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
143 | if (err != 0) | 144 | if (err != 0) |
144 | return err; | 145 | return err; |
145 | 146 | ||
147 | err = apic->cpu_mask_to_apicid(eligible_cpu, &dest); | ||
148 | if (err != 0) | ||
149 | return err; | ||
150 | |||
146 | if (limit == UV_AFFINITY_CPU) | 151 | if (limit == UV_AFFINITY_CPU) |
147 | irq_set_status_flags(irq, IRQ_NO_BALANCING); | 152 | irq_set_status_flags(irq, IRQ_NO_BALANCING); |
148 | else | 153 | else |
@@ -159,7 +164,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
159 | entry->polarity = 0; | 164 | entry->polarity = 0; |
160 | entry->trigger = 0; | 165 | entry->trigger = 0; |
161 | entry->mask = 0; | 166 | entry->mask = 0; |
162 | entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); | 167 | entry->dest = dest; |
163 | 168 | ||
164 | mmr_pnode = uv_blade_to_pnode(mmr_blade); | 169 | mmr_pnode = uv_blade_to_pnode(mmr_blade); |
165 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); | 170 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); |