aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-24 07:01:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-24 07:01:18 -0400
commit78fea6334f725f1a55cb5761730ceab64255cf1a (patch)
tree5413075a2bc54583d18b79a698bdd7b539c00cd6
parente0bc833d108e8caba1918218a0b2be7a71080d17 (diff)
parentbed9df97b39e73a4607189f2c4b9fb89cc3f7f59 (diff)
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Thomas Gleixner: "A set of fixes mostly for the ARM/GIC world: - Fix the MSI affinity handling in the ls-scfg irq chip driver so it updates and uses the effective affinity mask correctly - Prevent binding LPIs to offline CPUs and respect the Cavium erratum which requires that LPIs which belong to an offline NUMA node are not bound to a CPU on a different NUMA node. - Free only the amount of allocated interrupts in the GIC-V2M driver instead of trying to free log2(nrirqs). - Prevent emitting SYNC and VSYNC targetting non existing interrupt collections in the GIC-V3 ITS driver - Ensure that the GIV-V3 interrupt redistributor is correctly reprogrammed on CPU hotplug - Remove a stale unused helper function" * 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqdesc: Delete irq_desc_get_msi_desc() irqchip/gic-v3-its: Fix reprogramming of redistributors on CPU hotplug irqchip/gic-v3-its: Only emit VSYNC if targetting a valid collection irqchip/gic-v3-its: Only emit SYNC if targetting a valid collection irqchip/gic-v3-its: Don't bind LPI to unavailable NUMA node irqchip/gic-v2m: Fix SPI release on error path irqchip/ls-scfg-msi: Fix MSI affinity handling genirq/debugfs: Add missing IRQCHIP_SUPPORTS_LEVEL_MSI debug
-rw-r--r--drivers/irqchip/irq-gic-v2m.c2
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c62
-rw-r--r--drivers/irqchip/irq-ls-scfg-msi.c10
-rw-r--r--include/linux/irq.h1
-rw-r--r--include/linux/irqdesc.h5
-rw-r--r--kernel/irq/debugfs.c1
6 files changed, 60 insertions, 21 deletions
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 0f52d44b3f69..f5fe0100f9ff 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -199,7 +199,7 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
199 199
200fail: 200fail:
201 irq_domain_free_irqs_parent(domain, virq, nr_irqs); 201 irq_domain_free_irqs_parent(domain, virq, nr_irqs);
202 gicv2m_unalloc_msi(v2m, hwirq, get_count_order(nr_irqs)); 202 gicv2m_unalloc_msi(v2m, hwirq, nr_irqs);
203 return err; 203 return err;
204} 204}
205 205
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 5377d7e2afba..d7842d312d3e 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -182,6 +182,22 @@ static struct its_collection *dev_event_to_col(struct its_device *its_dev,
182 return its->collections + its_dev->event_map.col_map[event]; 182 return its->collections + its_dev->event_map.col_map[event];
183} 183}
184 184
185static struct its_collection *valid_col(struct its_collection *col)
186{
187 if (WARN_ON_ONCE(col->target_address & GENMASK_ULL(0, 15)))
188 return NULL;
189
190 return col;
191}
192
193static struct its_vpe *valid_vpe(struct its_node *its, struct its_vpe *vpe)
194{
195 if (valid_col(its->collections + vpe->col_idx))
196 return vpe;
197
198 return NULL;
199}
200
185/* 201/*
186 * ITS command descriptors - parameters to be encoded in a command 202 * ITS command descriptors - parameters to be encoded in a command
187 * block. 203 * block.
@@ -439,7 +455,7 @@ static struct its_collection *its_build_mapti_cmd(struct its_node *its,
439 455
440 its_fixup_cmd(cmd); 456 its_fixup_cmd(cmd);
441 457
442 return col; 458 return valid_col(col);
443} 459}
444 460
445static struct its_collection *its_build_movi_cmd(struct its_node *its, 461static struct its_collection *its_build_movi_cmd(struct its_node *its,
@@ -458,7 +474,7 @@ static struct its_collection *its_build_movi_cmd(struct its_node *its,
458 474
459 its_fixup_cmd(cmd); 475 its_fixup_cmd(cmd);
460 476
461 return col; 477 return valid_col(col);
462} 478}
463 479
464static struct its_collection *its_build_discard_cmd(struct its_node *its, 480static struct its_collection *its_build_discard_cmd(struct its_node *its,
@@ -476,7 +492,7 @@ static struct its_collection *its_build_discard_cmd(struct its_node *its,
476 492
477 its_fixup_cmd(cmd); 493 its_fixup_cmd(cmd);
478 494
479 return col; 495 return valid_col(col);
480} 496}
481 497
482static struct its_collection *its_build_inv_cmd(struct its_node *its, 498static struct its_collection *its_build_inv_cmd(struct its_node *its,
@@ -494,7 +510,7 @@ static struct its_collection *its_build_inv_cmd(struct its_node *its,
494 510
495 its_fixup_cmd(cmd); 511 its_fixup_cmd(cmd);
496 512
497 return col; 513 return valid_col(col);
498} 514}
499 515
500static struct its_collection *its_build_int_cmd(struct its_node *its, 516static struct its_collection *its_build_int_cmd(struct its_node *its,
@@ -512,7 +528,7 @@ static struct its_collection *its_build_int_cmd(struct its_node *its,
512 528
513 its_fixup_cmd(cmd); 529 its_fixup_cmd(cmd);
514 530
515 return col; 531 return valid_col(col);
516} 532}
517 533
518static struct its_collection *its_build_clear_cmd(struct its_node *its, 534static struct its_collection *its_build_clear_cmd(struct its_node *its,
@@ -530,7 +546,7 @@ static struct its_collection *its_build_clear_cmd(struct its_node *its,
530 546
531 its_fixup_cmd(cmd); 547 its_fixup_cmd(cmd);
532 548
533 return col; 549 return valid_col(col);
534} 550}
535 551
536static struct its_collection *its_build_invall_cmd(struct its_node *its, 552static struct its_collection *its_build_invall_cmd(struct its_node *its,
@@ -554,7 +570,7 @@ static struct its_vpe *its_build_vinvall_cmd(struct its_node *its,
554 570
555 its_fixup_cmd(cmd); 571 its_fixup_cmd(cmd);
556 572
557 return desc->its_vinvall_cmd.vpe; 573 return valid_vpe(its, desc->its_vinvall_cmd.vpe);
558} 574}
559 575
560static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, 576static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
@@ -576,7 +592,7 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
576 592
577 its_fixup_cmd(cmd); 593 its_fixup_cmd(cmd);
578 594
579 return desc->its_vmapp_cmd.vpe; 595 return valid_vpe(its, desc->its_vmapp_cmd.vpe);
580} 596}
581 597
582static struct its_vpe *its_build_vmapti_cmd(struct its_node *its, 598static struct its_vpe *its_build_vmapti_cmd(struct its_node *its,
@@ -599,7 +615,7 @@ static struct its_vpe *its_build_vmapti_cmd(struct its_node *its,
599 615
600 its_fixup_cmd(cmd); 616 its_fixup_cmd(cmd);
601 617
602 return desc->its_vmapti_cmd.vpe; 618 return valid_vpe(its, desc->its_vmapti_cmd.vpe);
603} 619}
604 620
605static struct its_vpe *its_build_vmovi_cmd(struct its_node *its, 621static struct its_vpe *its_build_vmovi_cmd(struct its_node *its,
@@ -622,7 +638,7 @@ static struct its_vpe *its_build_vmovi_cmd(struct its_node *its,
622 638
623 its_fixup_cmd(cmd); 639 its_fixup_cmd(cmd);
624 640
625 return desc->its_vmovi_cmd.vpe; 641 return valid_vpe(its, desc->its_vmovi_cmd.vpe);
626} 642}
627 643
628static struct its_vpe *its_build_vmovp_cmd(struct its_node *its, 644static struct its_vpe *its_build_vmovp_cmd(struct its_node *its,
@@ -640,7 +656,7 @@ static struct its_vpe *its_build_vmovp_cmd(struct its_node *its,
640 656
641 its_fixup_cmd(cmd); 657 its_fixup_cmd(cmd);
642 658
643 return desc->its_vmovp_cmd.vpe; 659 return valid_vpe(its, desc->its_vmovp_cmd.vpe);
644} 660}
645 661
646static u64 its_cmd_ptr_to_offset(struct its_node *its, 662static u64 its_cmd_ptr_to_offset(struct its_node *its,
@@ -1824,11 +1840,16 @@ static int its_alloc_tables(struct its_node *its)
1824 1840
1825static int its_alloc_collections(struct its_node *its) 1841static int its_alloc_collections(struct its_node *its)
1826{ 1842{
1843 int i;
1844
1827 its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections), 1845 its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections),
1828 GFP_KERNEL); 1846 GFP_KERNEL);
1829 if (!its->collections) 1847 if (!its->collections)
1830 return -ENOMEM; 1848 return -ENOMEM;
1831 1849
1850 for (i = 0; i < nr_cpu_ids; i++)
1851 its->collections[i].target_address = ~0ULL;
1852
1832 return 0; 1853 return 0;
1833} 1854}
1834 1855
@@ -2310,7 +2331,14 @@ static int its_irq_domain_activate(struct irq_domain *domain,
2310 cpu_mask = cpumask_of_node(its_dev->its->numa_node); 2331 cpu_mask = cpumask_of_node(its_dev->its->numa_node);
2311 2332
2312 /* Bind the LPI to the first possible CPU */ 2333 /* Bind the LPI to the first possible CPU */
2313 cpu = cpumask_first(cpu_mask); 2334 cpu = cpumask_first_and(cpu_mask, cpu_online_mask);
2335 if (cpu >= nr_cpu_ids) {
2336 if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144)
2337 return -EINVAL;
2338
2339 cpu = cpumask_first(cpu_online_mask);
2340 }
2341
2314 its_dev->event_map.col_map[event] = cpu; 2342 its_dev->event_map.col_map[event] = cpu;
2315 irq_data_update_effective_affinity(d, cpumask_of(cpu)); 2343 irq_data_update_effective_affinity(d, cpumask_of(cpu));
2316 2344
@@ -3399,6 +3427,16 @@ static int redist_disable_lpis(void)
3399 u64 timeout = USEC_PER_SEC; 3427 u64 timeout = USEC_PER_SEC;
3400 u64 val; 3428 u64 val;
3401 3429
3430 /*
3431 * If coming via a CPU hotplug event, we don't need to disable
3432 * LPIs before trying to re-enable them. They are already
3433 * configured and all is well in the world. Detect this case
3434 * by checking the allocation of the pending table for the
3435 * current CPU.
3436 */
3437 if (gic_data_rdist()->pend_page)
3438 return 0;
3439
3402 if (!gic_rdists_supports_plpis()) { 3440 if (!gic_rdists_supports_plpis()) {
3403 pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); 3441 pr_info("CPU%d: LPIs not supported\n", smp_processor_id());
3404 return -ENXIO; 3442 return -ENXIO;
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 1ec3bfe56693..c671b3212010 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -93,8 +93,12 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
93 msg->address_lo = lower_32_bits(msi_data->msiir_addr); 93 msg->address_lo = lower_32_bits(msi_data->msiir_addr);
94 msg->data = data->hwirq; 94 msg->data = data->hwirq;
95 95
96 if (msi_affinity_flag) 96 if (msi_affinity_flag) {
97 msg->data |= cpumask_first(data->common->affinity); 97 const struct cpumask *mask;
98
99 mask = irq_data_get_effective_affinity_mask(data);
100 msg->data |= cpumask_first(mask);
101 }
98 102
99 iommu_dma_map_msi_msg(data->irq, msg); 103 iommu_dma_map_msi_msg(data->irq, msg);
100} 104}
@@ -121,7 +125,7 @@ static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
121 return -EINVAL; 125 return -EINVAL;
122 } 126 }
123 127
124 cpumask_copy(irq_data->common->affinity, mask); 128 irq_data_update_effective_affinity(irq_data, cpumask_of(cpu));
125 129
126 return IRQ_SET_MASK_OK; 130 return IRQ_SET_MASK_OK;
127} 131}
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 4bd2f34947f4..201de12a9957 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -503,6 +503,7 @@ struct irq_chip {
503 * IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip 503 * IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip
504 * IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask 504 * IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask
505 * IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode 505 * IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode
506 * IRQCHIP_SUPPORTS_LEVEL_MSI Chip can provide two doorbells for Level MSIs
506 */ 507 */
507enum { 508enum {
508 IRQCHIP_SET_TYPE_MASKED = (1 << 0), 509 IRQCHIP_SET_TYPE_MASKED = (1 << 0),
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 25b33b664537..dd1e40ddac7d 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -145,11 +145,6 @@ static inline void *irq_desc_get_handler_data(struct irq_desc *desc)
145 return desc->irq_common_data.handler_data; 145 return desc->irq_common_data.handler_data;
146} 146}
147 147
148static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc)
149{
150 return desc->irq_common_data.msi_desc;
151}
152
153/* 148/*
154 * Architectures call this to let the generic IRQ layer 149 * Architectures call this to let the generic IRQ layer
155 * handle an interrupt. 150 * handle an interrupt.
diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c
index 4dadeb3d6666..6f636136cccc 100644
--- a/kernel/irq/debugfs.c
+++ b/kernel/irq/debugfs.c
@@ -55,6 +55,7 @@ static const struct irq_bit_descr irqchip_flags[] = {
55 BIT_MASK_DESCR(IRQCHIP_SKIP_SET_WAKE), 55 BIT_MASK_DESCR(IRQCHIP_SKIP_SET_WAKE),
56 BIT_MASK_DESCR(IRQCHIP_ONESHOT_SAFE), 56 BIT_MASK_DESCR(IRQCHIP_ONESHOT_SAFE),
57 BIT_MASK_DESCR(IRQCHIP_EOI_THREADED), 57 BIT_MASK_DESCR(IRQCHIP_EOI_THREADED),
58 BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI),
58}; 59};
59 60
60static void 61static void