Skip to content

Commit d01fd16

Browse files
author
Marc Zyngier
committed
irqchip/gic-v3: Workaround Cavium erratum 38539 when reading GICD_TYPER2
Despite the architecture spec requiring that reserved registers in the GIC distributor memory map are RES0 (and thus are not allowed to generate an exception), the Cavium ThunderX (aka TX1) SoC explodes as such: [ 0.000000] GICv3: GIC: Using split EOI/Deactivate mode [ 0.000000] GICv3: 128 SPIs implemented [ 0.000000] GICv3: 0 Extended SPIs implemented [ 0.000000] Internal error: synchronous external abort: 96000210 [#1] SMP [ 0.000000] Modules linked in: [ 0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.0-rc4-00035-g3cf6a3d5725f #7956 [ 0.000000] Hardware name: cavium,thunder-88xx (DT) [ 0.000000] pstate: 60000085 (nZCv daIf -PAN -UAO) [ 0.000000] pc : __raw_readl+0x0/0x8 [ 0.000000] lr : gic_init_bases+0x110/0x560 [ 0.000000] sp : ffff800011243d90 [ 0.000000] x29: ffff800011243d90 x28: 0000000000000000 [ 0.000000] x27: 0000000000000018 x26: 0000000000000002 [ 0.000000] x25: ffff8000116f0000 x24: ffff000fbe6a2c80 [ 0.000000] x23: 0000000000000000 x22: ffff010fdc322b68 [ 0.000000] x21: ffff800010a7a208 x20: 00000000009b0404 [ 0.000000] x19: ffff80001124dad0 x18: 0000000000000010 [ 0.000000] x17: 000000004d8d492b x16: 00000000f67eb9af [ 0.000000] x15: ffffffffffffffff x14: ffff800011249908 [ 0.000000] x13: ffff800091243ae7 x12: ffff800011243af4 [ 0.000000] x11: ffff80001126e000 x10: ffff800011243a70 [ 0.000000] x9 : 00000000ffffffd0 x8 : ffff80001069c828 [ 0.000000] x7 : 0000000000000059 x6 : ffff8000113fb4d1 [ 0.000000] x5 : 0000000000000001 x4 : 0000000000000000 [ 0.000000] x3 : 0000000000000000 x2 : 0000000000000000 [ 0.000000] x1 : 0000000000000000 x0 : ffff8000116f000c [ 0.000000] Call trace: [ 0.000000] __raw_readl+0x0/0x8 [ 0.000000] gic_of_init+0x188/0x224 [ 0.000000] of_irq_init+0x200/0x3cc [ 0.000000] irqchip_init+0x1c/0x40 [ 0.000000] init_IRQ+0x160/0x1d0 [ 0.000000] start_kernel+0x2ec/0x4b8 [ 0.000000] Code: a8c47bfd d65f03c0 d538d080 d65f03c0 (b9400000) when reading the GICv4.1 GICD_TYPER2 register, which is unexpected... Work around it by adding a new quirk for the following variants: ThunderX: CN88xx OCTEON TX: CN83xx, CN81xx OCTEON TX2: CN93xx, CN96xx, CN98xx, CNF95xx* and use this flag to avoid accessing GICD_TYPER2. Note that all reserved registers (including redistributors and ITS) are impacted by this erratum, but that only GICD_TYPER2 has to be worked around so far. Signed-off-by: Marc Zyngier <[email protected]> Tested-by: Robert Richter <[email protected]> Tested-by: Mark Salter <[email protected]> Tested-by: Tim Harvey <[email protected]> Acked-by: Catalin Marinas <[email protected]> Acked-by: Robert Richter <[email protected]> Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected]
1 parent 5186a6c commit d01fd16

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

Documentation/arm64/silicon-errata.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ stable kernels.
108108
+----------------+-----------------+-----------------+-----------------------------+
109109
| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
110110
+----------------+-----------------+-----------------+-----------------------------+
111+
| Cavium | ThunderX GICv3 | #38539 | N/A |
112+
+----------------+-----------------+-----------------+-----------------------------+
111113
| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
112114
+----------------+-----------------+-----------------+-----------------------------+
113115
| Cavium | ThunderX Core | #30115 | CAVIUM_ERRATUM_30115 |

drivers/irqchip/irq-gic-v3.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80)
3535

3636
#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0)
37+
#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1)
3738

3839
struct redist_region {
3940
void __iomem *redist_base;
@@ -1464,6 +1465,15 @@ static bool gic_enable_quirk_msm8996(void *data)
14641465
return true;
14651466
}
14661467

1468+
static bool gic_enable_quirk_cavium_38539(void *data)
1469+
{
1470+
struct gic_chip_data *d = data;
1471+
1472+
d->flags |= FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539;
1473+
1474+
return true;
1475+
}
1476+
14671477
static bool gic_enable_quirk_hip06_07(void *data)
14681478
{
14691479
struct gic_chip_data *d = data;
@@ -1502,6 +1512,19 @@ static const struct gic_quirk gic_quirks[] = {
15021512
.mask = 0xffffffff,
15031513
.init = gic_enable_quirk_hip06_07,
15041514
},
1515+
{
1516+
/*
1517+
* Reserved register accesses generate a Synchronous
1518+
* External Abort. This erratum applies to:
1519+
* - ThunderX: CN88xx
1520+
* - OCTEON TX: CN83xx, CN81xx
1521+
* - OCTEON TX2: CN93xx, CN96xx, CN98xx, CNF95xx*
1522+
*/
1523+
.desc = "GICv3: Cavium erratum 38539",
1524+
.iidr = 0xa000034c,
1525+
.mask = 0xe8f00fff,
1526+
.init = gic_enable_quirk_cavium_38539,
1527+
},
15051528
{
15061529
}
15071530
};
@@ -1577,7 +1600,12 @@ static int __init gic_init_bases(void __iomem *dist_base,
15771600
pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32);
15781601
pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR);
15791602

1580-
gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2);
1603+
/*
1604+
* ThunderX1 explodes on reading GICD_TYPER2, in violation of the
1605+
* architecture spec (which says that reserved registers are RES0).
1606+
*/
1607+
if (!(gic_data.flags & FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539))
1608+
gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2);
15811609

15821610
gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
15831611
&gic_data);

0 commit comments

Comments
 (0)