Skip to content

Commit 78fea63

Browse files
committed
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
2 parents e0bc833 + bed9df9 commit 78fea63

File tree

6 files changed

+60
-21
lines changed

6 files changed

+60
-21
lines changed

drivers/irqchip/irq-gic-v2m.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
199199

200200
fail:
201201
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);
203203
return err;
204204
}
205205

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,22 @@ static struct its_collection *dev_event_to_col(struct its_device *its_dev,
182182
return its->collections + its_dev->event_map.col_map[event];
183183
}
184184

185+
static 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+
193+
static 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+
185201
/*
186202
* ITS command descriptors - parameters to be encoded in a command
187203
* block.
@@ -439,7 +455,7 @@ static struct its_collection *its_build_mapti_cmd(struct its_node *its,
439455

440456
its_fixup_cmd(cmd);
441457

442-
return col;
458+
return valid_col(col);
443459
}
444460

445461
static 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,
458474

459475
its_fixup_cmd(cmd);
460476

461-
return col;
477+
return valid_col(col);
462478
}
463479

464480
static 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,
476492

477493
its_fixup_cmd(cmd);
478494

479-
return col;
495+
return valid_col(col);
480496
}
481497

482498
static 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,
494510

495511
its_fixup_cmd(cmd);
496512

497-
return col;
513+
return valid_col(col);
498514
}
499515

500516
static 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,
512528

513529
its_fixup_cmd(cmd);
514530

515-
return col;
531+
return valid_col(col);
516532
}
517533

518534
static 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,
530546

531547
its_fixup_cmd(cmd);
532548

533-
return col;
549+
return valid_col(col);
534550
}
535551

536552
static 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,
554570

555571
its_fixup_cmd(cmd);
556572

557-
return desc->its_vinvall_cmd.vpe;
573+
return valid_vpe(its, desc->its_vinvall_cmd.vpe);
558574
}
559575

560576
static 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,
576592

577593
its_fixup_cmd(cmd);
578594

579-
return desc->its_vmapp_cmd.vpe;
595+
return valid_vpe(its, desc->its_vmapp_cmd.vpe);
580596
}
581597

582598
static 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,
599615

600616
its_fixup_cmd(cmd);
601617

602-
return desc->its_vmapti_cmd.vpe;
618+
return valid_vpe(its, desc->its_vmapti_cmd.vpe);
603619
}
604620

605621
static 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,
622638

623639
its_fixup_cmd(cmd);
624640

625-
return desc->its_vmovi_cmd.vpe;
641+
return valid_vpe(its, desc->its_vmovi_cmd.vpe);
626642
}
627643

628644
static 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,
640656

641657
its_fixup_cmd(cmd);
642658

643-
return desc->its_vmovp_cmd.vpe;
659+
return valid_vpe(its, desc->its_vmovp_cmd.vpe);
644660
}
645661

646662
static u64 its_cmd_ptr_to_offset(struct its_node *its,
@@ -1824,11 +1840,16 @@ static int its_alloc_tables(struct its_node *its)
18241840

18251841
static int its_alloc_collections(struct its_node *its)
18261842
{
1843+
int i;
1844+
18271845
its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections),
18281846
GFP_KERNEL);
18291847
if (!its->collections)
18301848
return -ENOMEM;
18311849

1850+
for (i = 0; i < nr_cpu_ids; i++)
1851+
its->collections[i].target_address = ~0ULL;
1852+
18321853
return 0;
18331854
}
18341855

@@ -2310,7 +2331,14 @@ static int its_irq_domain_activate(struct irq_domain *domain,
23102331
cpu_mask = cpumask_of_node(its_dev->its->numa_node);
23112332

23122333
/* 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+
23142342
its_dev->event_map.col_map[event] = cpu;
23152343
irq_data_update_effective_affinity(d, cpumask_of(cpu));
23162344

@@ -3399,6 +3427,16 @@ static int redist_disable_lpis(void)
33993427
u64 timeout = USEC_PER_SEC;
34003428
u64 val;
34013429

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+
34023440
if (!gic_rdists_supports_plpis()) {
34033441
pr_info("CPU%d: LPIs not supported\n", smp_processor_id());
34043442
return -ENXIO;

drivers/irqchip/irq-ls-scfg-msi.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,12 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
9393
msg->address_lo = lower_32_bits(msi_data->msiir_addr);
9494
msg->data = data->hwirq;
9595

96-
if (msi_affinity_flag)
97-
msg->data |= cpumask_first(data->common->affinity);
96+
if (msi_affinity_flag) {
97+
const struct cpumask *mask;
98+
99+
mask = irq_data_get_effective_affinity_mask(data);
100+
msg->data |= cpumask_first(mask);
101+
}
98102

99103
iommu_dma_map_msi_msg(data->irq, msg);
100104
}
@@ -121,7 +125,7 @@ static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
121125
return -EINVAL;
122126
}
123127

124-
cpumask_copy(irq_data->common->affinity, mask);
128+
irq_data_update_effective_affinity(irq_data, cpumask_of(cpu));
125129

126130
return IRQ_SET_MASK_OK;
127131
}

include/linux/irq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ struct irq_chip {
503503
* IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip
504504
* IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask
505505
* IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode
506+
* IRQCHIP_SUPPORTS_LEVEL_MSI Chip can provide two doorbells for Level MSIs
506507
*/
507508
enum {
508509
IRQCHIP_SET_TYPE_MASKED = (1 << 0),

include/linux/irqdesc.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,6 @@ static inline void *irq_desc_get_handler_data(struct irq_desc *desc)
145145
return desc->irq_common_data.handler_data;
146146
}
147147

148-
static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc)
149-
{
150-
return desc->irq_common_data.msi_desc;
151-
}
152-
153148
/*
154149
* Architectures call this to let the generic IRQ layer
155150
* handle an interrupt.

kernel/irq/debugfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static const struct irq_bit_descr irqchip_flags[] = {
5555
BIT_MASK_DESCR(IRQCHIP_SKIP_SET_WAKE),
5656
BIT_MASK_DESCR(IRQCHIP_ONESHOT_SAFE),
5757
BIT_MASK_DESCR(IRQCHIP_EOI_THREADED),
58+
BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI),
5859
};
5960

6061
static void

0 commit comments

Comments
 (0)