Skip to content

Commit 71c87bd

Browse files
committed
Merge tag 'irqchip-fixes-4.0' of git://git.infradead.org/users/jcooper/linux
Pull irqchip fixes from Jason Cooper: "armada-370-xp: - Chained per-cpu interrupts gic{,-v3,v3-its}" - Various fixes for safer operation" * tag 'irqchip-fixes-4.0' of git://git.infradead.org/users/jcooper/linux: irqchip: gicv3-its: Support safe initialization irqchip: gicv3-its: Define macros for GITS_CTLR fields irqchip: gicv3-its: Add limitation to page order irqchip: gicv3-its: Use 64KB page as default granule irqchip: gicv3-its: Zero itt before handling to hardware irqchip: gic-v3: Fix out of bounds access to cpu_logical_map irqchip: gic: Fix unsafe locking reported by lockdep irqchip: gicv3-its: Fix unsafe locking reported by lockdep irqchip: gicv3-its: Iterate over PCI aliases to generate ITS configuration irqchip: gicv3-its: Allocate enough memory for the full range of DeviceID irqchip: gicv3-its: Fix ITS CPU init irqchip: armada-370-xp: Fix chained per-cpu interrupts
2 parents 7cd9beb + aaa95f7 commit 71c87bd

File tree

5 files changed

+166
-39
lines changed

5 files changed

+166
-39
lines changed

drivers/irqchip/irq-armada-370-xp.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static void __iomem *per_cpu_int_base;
6969
static void __iomem *main_int_base;
7070
static struct irq_domain *armada_370_xp_mpic_domain;
7171
static u32 doorbell_mask_reg;
72+
static int parent_irq;
7273
#ifdef CONFIG_PCI_MSI
7374
static struct irq_domain *armada_370_xp_msi_domain;
7475
static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR);
@@ -356,6 +357,7 @@ static int armada_xp_mpic_secondary_init(struct notifier_block *nfb,
356357
{
357358
if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
358359
armada_xp_mpic_smp_cpu_init();
360+
359361
return NOTIFY_OK;
360362
}
361363

@@ -364,6 +366,20 @@ static struct notifier_block armada_370_xp_mpic_cpu_notifier = {
364366
.priority = 100,
365367
};
366368

369+
static int mpic_cascaded_secondary_init(struct notifier_block *nfb,
370+
unsigned long action, void *hcpu)
371+
{
372+
if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
373+
enable_percpu_irq(parent_irq, IRQ_TYPE_NONE);
374+
375+
return NOTIFY_OK;
376+
}
377+
378+
static struct notifier_block mpic_cascaded_cpu_notifier = {
379+
.notifier_call = mpic_cascaded_secondary_init,
380+
.priority = 100,
381+
};
382+
367383
#endif /* CONFIG_SMP */
368384

369385
static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
@@ -539,7 +555,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
539555
struct device_node *parent)
540556
{
541557
struct resource main_int_res, per_cpu_int_res;
542-
int parent_irq, nr_irqs, i;
558+
int nr_irqs, i;
543559
u32 control;
544560

545561
BUG_ON(of_address_to_resource(node, 0, &main_int_res));
@@ -587,6 +603,9 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
587603
register_cpu_notifier(&armada_370_xp_mpic_cpu_notifier);
588604
#endif
589605
} else {
606+
#ifdef CONFIG_SMP
607+
register_cpu_notifier(&mpic_cascaded_cpu_notifier);
608+
#endif
590609
irq_set_chained_handler(parent_irq,
591610
armada_370_xp_mpic_handle_cascade_irq);
592611
}

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

Lines changed: 128 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,14 @@ static void its_send_single_command(struct its_node *its,
416416
{
417417
struct its_cmd_block *cmd, *sync_cmd, *next_cmd;
418418
struct its_collection *sync_col;
419+
unsigned long flags;
419420

420-
raw_spin_lock(&its->lock);
421+
raw_spin_lock_irqsave(&its->lock, flags);
421422

422423
cmd = its_allocate_entry(its);
423424
if (!cmd) { /* We're soooooo screewed... */
424425
pr_err_ratelimited("ITS can't allocate, dropping command\n");
425-
raw_spin_unlock(&its->lock);
426+
raw_spin_unlock_irqrestore(&its->lock, flags);
426427
return;
427428
}
428429
sync_col = builder(cmd, desc);
@@ -442,7 +443,7 @@ static void its_send_single_command(struct its_node *its,
442443

443444
post:
444445
next_cmd = its_post_commands(its);
445-
raw_spin_unlock(&its->lock);
446+
raw_spin_unlock_irqrestore(&its->lock, flags);
446447

447448
its_wait_for_range_completion(its, cmd, next_cmd);
448449
}
@@ -799,21 +800,43 @@ static int its_alloc_tables(struct its_node *its)
799800
{
800801
int err;
801802
int i;
802-
int psz = PAGE_SIZE;
803+
int psz = SZ_64K;
803804
u64 shr = GITS_BASER_InnerShareable;
804805

805806
for (i = 0; i < GITS_BASER_NR_REGS; i++) {
806807
u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
807808
u64 type = GITS_BASER_TYPE(val);
808809
u64 entry_size = GITS_BASER_ENTRY_SIZE(val);
810+
int order = get_order(psz);
811+
int alloc_size;
809812
u64 tmp;
810813
void *base;
811814

812815
if (type == GITS_BASER_TYPE_NONE)
813816
continue;
814817

815-
/* We're lazy and only allocate a single page for now */
816-
base = (void *)get_zeroed_page(GFP_KERNEL);
818+
/*
819+
* Allocate as many entries as required to fit the
820+
* range of device IDs that the ITS can grok... The ID
821+
* space being incredibly sparse, this results in a
822+
* massive waste of memory.
823+
*
824+
* For other tables, only allocate a single page.
825+
*/
826+
if (type == GITS_BASER_TYPE_DEVICE) {
827+
u64 typer = readq_relaxed(its->base + GITS_TYPER);
828+
u32 ids = GITS_TYPER_DEVBITS(typer);
829+
830+
order = get_order((1UL << ids) * entry_size);
831+
if (order >= MAX_ORDER) {
832+
order = MAX_ORDER - 1;
833+
pr_warn("%s: Device Table too large, reduce its page order to %u\n",
834+
its->msi_chip.of_node->full_name, order);
835+
}
836+
}
837+
838+
alloc_size = (1 << order) * PAGE_SIZE;
839+
base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
817840
if (!base) {
818841
err = -ENOMEM;
819842
goto out_free;
@@ -841,7 +864,7 @@ static int its_alloc_tables(struct its_node *its)
841864
break;
842865
}
843866

844-
val |= (PAGE_SIZE / psz) - 1;
867+
val |= (alloc_size / psz) - 1;
845868

846869
writeq_relaxed(val, its->base + GITS_BASER + i * 8);
847870
tmp = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -882,7 +905,7 @@ static int its_alloc_tables(struct its_node *its)
882905
}
883906

884907
pr_info("ITS: allocated %d %s @%lx (psz %dK, shr %d)\n",
885-
(int)(PAGE_SIZE / entry_size),
908+
(int)(alloc_size / entry_size),
886909
its_base_type_string[type],
887910
(unsigned long)virt_to_phys(base),
888911
psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT);
@@ -1020,8 +1043,9 @@ static void its_cpu_init_collection(void)
10201043
static struct its_device *its_find_device(struct its_node *its, u32 dev_id)
10211044
{
10221045
struct its_device *its_dev = NULL, *tmp;
1046+
unsigned long flags;
10231047

1024-
raw_spin_lock(&its->lock);
1048+
raw_spin_lock_irqsave(&its->lock, flags);
10251049

10261050
list_for_each_entry(tmp, &its->its_device_list, entry) {
10271051
if (tmp->device_id == dev_id) {
@@ -1030,7 +1054,7 @@ static struct its_device *its_find_device(struct its_node *its, u32 dev_id)
10301054
}
10311055
}
10321056

1033-
raw_spin_unlock(&its->lock);
1057+
raw_spin_unlock_irqrestore(&its->lock, flags);
10341058

10351059
return its_dev;
10361060
}
@@ -1040,6 +1064,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
10401064
{
10411065
struct its_device *dev;
10421066
unsigned long *lpi_map;
1067+
unsigned long flags;
10431068
void *itt;
10441069
int lpi_base;
10451070
int nr_lpis;
@@ -1056,7 +1081,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
10561081
nr_ites = max(2UL, roundup_pow_of_two(nvecs));
10571082
sz = nr_ites * its->ite_size;
10581083
sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
1059-
itt = kmalloc(sz, GFP_KERNEL);
1084+
itt = kzalloc(sz, GFP_KERNEL);
10601085
lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
10611086

10621087
if (!dev || !itt || !lpi_map) {
@@ -1075,9 +1100,9 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
10751100
dev->device_id = dev_id;
10761101
INIT_LIST_HEAD(&dev->entry);
10771102

1078-
raw_spin_lock(&its->lock);
1103+
raw_spin_lock_irqsave(&its->lock, flags);
10791104
list_add(&dev->entry, &its->its_device_list);
1080-
raw_spin_unlock(&its->lock);
1105+
raw_spin_unlock_irqrestore(&its->lock, flags);
10811106

10821107
/* Bind the device to the first possible CPU */
10831108
cpu = cpumask_first(cpu_online_mask);
@@ -1091,9 +1116,11 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
10911116

10921117
static void its_free_device(struct its_device *its_dev)
10931118
{
1094-
raw_spin_lock(&its_dev->its->lock);
1119+
unsigned long flags;
1120+
1121+
raw_spin_lock_irqsave(&its_dev->its->lock, flags);
10951122
list_del(&its_dev->entry);
1096-
raw_spin_unlock(&its_dev->its->lock);
1123+
raw_spin_unlock_irqrestore(&its_dev->its->lock, flags);
10971124
kfree(its_dev->itt);
10981125
kfree(its_dev);
10991126
}
@@ -1112,31 +1139,69 @@ static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq)
11121139
return 0;
11131140
}
11141141

1142+
struct its_pci_alias {
1143+
struct pci_dev *pdev;
1144+
u32 dev_id;
1145+
u32 count;
1146+
};
1147+
1148+
static int its_pci_msi_vec_count(struct pci_dev *pdev)
1149+
{
1150+
int msi, msix;
1151+
1152+
msi = max(pci_msi_vec_count(pdev), 0);
1153+
msix = max(pci_msix_vec_count(pdev), 0);
1154+
1155+
return max(msi, msix);
1156+
}
1157+
1158+
static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data)
1159+
{
1160+
struct its_pci_alias *dev_alias = data;
1161+
1162+
dev_alias->dev_id = alias;
1163+
if (pdev != dev_alias->pdev)
1164+
dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev);
1165+
1166+
return 0;
1167+
}
1168+
11151169
static int its_msi_prepare(struct irq_domain *domain, struct device *dev,
11161170
int nvec, msi_alloc_info_t *info)
11171171
{
11181172
struct pci_dev *pdev;
11191173
struct its_node *its;
1120-
u32 dev_id;
11211174
struct its_device *its_dev;
1175+
struct its_pci_alias dev_alias;
11221176

11231177
if (!dev_is_pci(dev))
11241178
return -EINVAL;
11251179

11261180
pdev = to_pci_dev(dev);
1127-
dev_id = PCI_DEVID(pdev->bus->number, pdev->devfn);
1181+
dev_alias.pdev = pdev;
1182+
dev_alias.count = nvec;
1183+
1184+
pci_for_each_dma_alias(pdev, its_get_pci_alias, &dev_alias);
11281185
its = domain->parent->host_data;
11291186

1130-
its_dev = its_find_device(its, dev_id);
1131-
if (WARN_ON(its_dev))
1132-
return -EINVAL;
1187+
its_dev = its_find_device(its, dev_alias.dev_id);
1188+
if (its_dev) {
1189+
/*
1190+
* We already have seen this ID, probably through
1191+
* another alias (PCI bridge of some sort). No need to
1192+
* create the device.
1193+
*/
1194+
dev_dbg(dev, "Reusing ITT for devID %x\n", dev_alias.dev_id);
1195+
goto out;
1196+
}
11331197

1134-
its_dev = its_create_device(its, dev_id, nvec);
1198+
its_dev = its_create_device(its, dev_alias.dev_id, dev_alias.count);
11351199
if (!its_dev)
11361200
return -ENOMEM;
11371201

1138-
dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", nvec, ilog2(nvec));
1139-
1202+
dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n",
1203+
dev_alias.count, ilog2(dev_alias.count));
1204+
out:
11401205
info->scratchpad[0].ptr = its_dev;
11411206
info->scratchpad[1].ptr = dev;
11421207
return 0;
@@ -1255,6 +1320,34 @@ static const struct irq_domain_ops its_domain_ops = {
12551320
.deactivate = its_irq_domain_deactivate,
12561321
};
12571322

1323+
static int its_force_quiescent(void __iomem *base)
1324+
{
1325+
u32 count = 1000000; /* 1s */
1326+
u32 val;
1327+
1328+
val = readl_relaxed(base + GITS_CTLR);
1329+
if (val & GITS_CTLR_QUIESCENT)
1330+
return 0;
1331+
1332+
/* Disable the generation of all interrupts to this ITS */
1333+
val &= ~GITS_CTLR_ENABLE;
1334+
writel_relaxed(val, base + GITS_CTLR);
1335+
1336+
/* Poll GITS_CTLR and wait until ITS becomes quiescent */
1337+
while (1) {
1338+
val = readl_relaxed(base + GITS_CTLR);
1339+
if (val & GITS_CTLR_QUIESCENT)
1340+
return 0;
1341+
1342+
count--;
1343+
if (!count)
1344+
return -EBUSY;
1345+
1346+
cpu_relax();
1347+
udelay(1);
1348+
}
1349+
}
1350+
12581351
static int its_probe(struct device_node *node, struct irq_domain *parent)
12591352
{
12601353
struct resource res;
@@ -1283,6 +1376,13 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
12831376
goto out_unmap;
12841377
}
12851378

1379+
err = its_force_quiescent(its_base);
1380+
if (err) {
1381+
pr_warn("%s: failed to quiesce, giving up\n",
1382+
node->full_name);
1383+
goto out_unmap;
1384+
}
1385+
12861386
pr_info("ITS: %s\n", node->full_name);
12871387

12881388
its = kzalloc(sizeof(*its), GFP_KERNEL);
@@ -1323,7 +1423,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
13231423
writeq_relaxed(baser, its->base + GITS_CBASER);
13241424
tmp = readq_relaxed(its->base + GITS_CBASER);
13251425
writeq_relaxed(0, its->base + GITS_CWRITER);
1326-
writel_relaxed(1, its->base + GITS_CTLR);
1426+
writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
13271427

13281428
if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) {
13291429
pr_info("ITS: using cache flushing for cmd queue\n");
@@ -1382,12 +1482,11 @@ static bool gic_rdists_supports_plpis(void)
13821482

13831483
int its_cpu_init(void)
13841484
{
1385-
if (!gic_rdists_supports_plpis()) {
1386-
pr_info("CPU%d: LPIs not supported\n", smp_processor_id());
1387-
return -ENXIO;
1388-
}
1389-
13901485
if (!list_empty(&its_nodes)) {
1486+
if (!gic_rdists_supports_plpis()) {
1487+
pr_info("CPU%d: LPIs not supported\n", smp_processor_id());
1488+
return -ENXIO;
1489+
}
13911490
its_cpu_init_lpis();
13921491
its_cpu_init_collection();
13931492
}

drivers/irqchip/irq-gic-v3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
466466
tlist |= 1 << (mpidr & 0xf);
467467

468468
cpu = cpumask_next(cpu, mask);
469-
if (cpu == nr_cpu_ids)
469+
if (cpu >= nr_cpu_ids)
470470
goto out;
471471

472472
mpidr = cpu_logical_map(cpu);

0 commit comments

Comments
 (0)