Matthias Brugger aa2459
From: Linu Cherian <lcherian@marvell.com>
Matthias Brugger aa2459
Date: Mon, 7 Mar 2022 20:00:14 +0530
Matthias Brugger aa2459
Subject: irqchip/gic-v3: Workaround Marvell erratum 38545 when reading IAR
Matthias Brugger aa2459
Git-commit: 24a147bcef8ca039cb75d6d4b68c7cc339b11178
Matthias Brugger aa2459
Patch-mainline: v5.18-rc1
Matthias Brugger aa2459
References: jsc#SLE-24682
Matthias Brugger aa2459
Matthias Brugger aa2459
When a IAR register read races with a GIC interrupt RELEASE event,
Matthias Brugger aa2459
GIC-CPU interface could wrongly return a valid INTID to the CPU
Matthias Brugger aa2459
for an interrupt that is already released(non activated) instead of 0x3ff.
Matthias Brugger aa2459
Matthias Brugger aa2459
As a side effect, an interrupt handler could run twice, once with
Matthias Brugger aa2459
interrupt priority and then with idle priority.
Matthias Brugger aa2459
Matthias Brugger aa2459
As a workaround, gic_read_iar is updated so that it will return a
Matthias Brugger aa2459
valid interrupt ID only if there is a change in the active priority list
Matthias Brugger aa2459
after the IAR read on all the affected Silicons.
Matthias Brugger aa2459
Matthias Brugger aa2459
Since there are silicon variants where both 23154 and 38545 are applicable,
Matthias Brugger aa2459
workaround for erratum 23154 has been extended to address both of them.
Matthias Brugger aa2459
Matthias Brugger aa2459
Signed-off-by: Linu Cherian <lcherian@marvell.com>
Matthias Brugger aa2459
Reviewed-by: Marc Zyngier <maz@kernel.org>
Matthias Brugger aa2459
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Matthias Brugger aa2459
Link: https://lore.kernel.org/r/20220307143014.22758-1-lcherian@marvell.com
Matthias Brugger aa2459
Signed-off-by: Will Deacon <will@kernel.org>
Matthias Brugger aa2459
Signed-off-by: Matthias Brugger <mbrugger@suse.com>
Matthias Brugger aa2459
---
Matthias Brugger aa2459
 Documentation/arm64/silicon-errata.rst |  2 +-
Matthias Brugger aa2459
 arch/arm64/Kconfig                     |  8 ++++++--
Matthias Brugger aa2459
 arch/arm64/include/asm/arch_gicv3.h    | 23 +++++++++++++++++++++--
Matthias Brugger aa2459
 arch/arm64/include/asm/cputype.h       | 13 +++++++++++++
Matthias Brugger aa2459
 arch/arm64/kernel/cpu_errata.c         | 20 +++++++++++++++++---
Matthias Brugger aa2459
 5 files changed, 58 insertions(+), 8 deletions(-)
Matthias Brugger aa2459
Matthias Brugger aa2459
diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
Matthias Brugger aa2459
index ea281dd75517..466cb9e89047 100644
Matthias Brugger aa2459
--- a/Documentation/arm64/silicon-errata.rst
Matthias Brugger aa2459
+++ b/Documentation/arm64/silicon-errata.rst
Matthias Brugger aa2459
@@ -136,7 +136,7 @@ stable kernels.
Matthias Brugger aa2459
 +----------------+-----------------+-----------------+-----------------------------+
Matthias Brugger aa2459
 | Cavium         | ThunderX ITS    | #23144          | CAVIUM_ERRATUM_23144        |
Matthias Brugger aa2459
 +----------------+-----------------+-----------------+-----------------------------+
Matthias Brugger aa2459
-| Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154        |
Matthias Brugger aa2459
+| Cavium         | ThunderX GICv3  | #23154,38545    | CAVIUM_ERRATUM_23154        |
Matthias Brugger aa2459
 +----------------+-----------------+-----------------+-----------------------------+
Matthias Brugger aa2459
 | Cavium         | ThunderX GICv3  | #38539          | N/A                         |
Matthias Brugger aa2459
 +----------------+-----------------+-----------------+-----------------------------+
Matthias Brugger aa2459
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
Matthias Brugger aa2459
index cbcd42decb2a..b154aa98c43a 100644
Matthias Brugger aa2459
--- a/arch/arm64/Kconfig
Matthias Brugger aa2459
+++ b/arch/arm64/Kconfig
Matthias Brugger aa2459
@@ -890,13 +890,17 @@ config CAVIUM_ERRATUM_23144
Matthias Brugger aa2459
 	  If unsure, say Y.
Matthias Brugger aa2459
 
Matthias Brugger aa2459
 config CAVIUM_ERRATUM_23154
Matthias Brugger aa2459
-	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
Matthias Brugger aa2459
+	bool "Cavium errata 23154 and 38545: GICv3 lacks HW synchronisation"
Matthias Brugger aa2459
 	default y
Matthias Brugger aa2459
 	help
Matthias Brugger aa2459
-	  The gicv3 of ThunderX requires a modified version for
Matthias Brugger aa2459
+	  The ThunderX GICv3 implementation requires a modified version for
Matthias Brugger aa2459
 	  reading the IAR status to ensure data synchronization
Matthias Brugger aa2459
 	  (access to icc_iar1_el1 is not sync'ed before and after).
Matthias Brugger aa2459
 
Matthias Brugger aa2459
+	  It also suffers from erratum 38545 (also present on Marvell's
Matthias Brugger aa2459
+	  OcteonTX and OcteonTX2), resulting in deactivated interrupts being
Matthias Brugger aa2459
+	  spuriously presented to the CPU interface.
Matthias Brugger aa2459
+
Matthias Brugger aa2459
 	  If unsure, say Y.
Matthias Brugger aa2459
 
Matthias Brugger aa2459
 config CAVIUM_ERRATUM_27456
Matthias Brugger aa2459
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
Matthias Brugger aa2459
index 4ad22c3135db..8bd5afc7b692 100644
Matthias Brugger aa2459
--- a/arch/arm64/include/asm/arch_gicv3.h
Matthias Brugger aa2459
+++ b/arch/arm64/include/asm/arch_gicv3.h
Matthias Brugger aa2459
@@ -53,17 +53,36 @@ static inline u64 gic_read_iar_common(void)
Matthias Brugger aa2459
  * The gicv3 of ThunderX requires a modified version for reading the
Matthias Brugger aa2459
  * IAR status to ensure data synchronization (access to icc_iar1_el1
Matthias Brugger aa2459
  * is not sync'ed before and after).
Matthias Brugger aa2459
+ *
Matthias Brugger aa2459
+ * Erratum 38545
Matthias Brugger aa2459
+ *
Matthias Brugger aa2459
+ * When a IAR register read races with a GIC interrupt RELEASE event,
Matthias Brugger aa2459
+ * GIC-CPU interface could wrongly return a valid INTID to the CPU
Matthias Brugger aa2459
+ * for an interrupt that is already released(non activated) instead of 0x3ff.
Matthias Brugger aa2459
+ *
Matthias Brugger aa2459
+ * To workaround this, return a valid interrupt ID only if there is a change
Matthias Brugger aa2459
+ * in the active priority list after the IAR read.
Matthias Brugger aa2459
+ *
Matthias Brugger aa2459
+ * Common function used for both the workarounds since,
Matthias Brugger aa2459
+ * 1. On Thunderx 88xx 1.x both erratas are applicable.
Matthias Brugger aa2459
+ * 2. Having extra nops doesn't add any side effects for Silicons where
Matthias Brugger aa2459
+ *    erratum 23154 is not applicable.
Matthias Brugger aa2459
  */
Matthias Brugger aa2459
 static inline u64 gic_read_iar_cavium_thunderx(void)
Matthias Brugger aa2459
 {
Matthias Brugger aa2459
-	u64 irqstat;
Matthias Brugger aa2459
+	u64 irqstat, apr;
Matthias Brugger aa2459
 
Matthias Brugger aa2459
+	apr = read_sysreg_s(SYS_ICC_AP1R0_EL1);
Matthias Brugger aa2459
 	nops(8);
Matthias Brugger aa2459
 	irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1);
Matthias Brugger aa2459
 	nops(4);
Matthias Brugger aa2459
 	mb();
Matthias Brugger aa2459
 
Matthias Brugger aa2459
-	return irqstat;
Matthias Brugger aa2459
+	/* Max priority groups implemented is only 32 */
Matthias Brugger aa2459
+	if (likely(apr != read_sysreg_s(SYS_ICC_AP1R0_EL1)))
Matthias Brugger aa2459
+		return irqstat;
Matthias Brugger aa2459
+
Matthias Brugger aa2459
+	return 0x3ff;
Matthias Brugger aa2459
 }
Matthias Brugger aa2459
 
Matthias Brugger aa2459
 static inline void gic_write_ctlr(u32 val)
Matthias Brugger aa2459
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
Matthias Brugger aa2459
index 999b9149f856..4596e7ca29a3 100644
Matthias Brugger aa2459
--- a/arch/arm64/include/asm/cputype.h
Matthias Brugger aa2459
+++ b/arch/arm64/include/asm/cputype.h
Matthias Brugger aa2459
@@ -84,6 +84,13 @@
Matthias Brugger aa2459
 #define CAVIUM_CPU_PART_THUNDERX_81XX	0x0A2
Matthias Brugger aa2459
 #define CAVIUM_CPU_PART_THUNDERX_83XX	0x0A3
Matthias Brugger aa2459
 #define CAVIUM_CPU_PART_THUNDERX2	0x0AF
Matthias Brugger aa2459
+/* OcteonTx2 series */
Matthias Brugger aa2459
+#define CAVIUM_CPU_PART_OCTX2_98XX	0x0B1
Matthias Brugger aa2459
+#define CAVIUM_CPU_PART_OCTX2_96XX	0x0B2
Matthias Brugger aa2459
+#define CAVIUM_CPU_PART_OCTX2_95XX	0x0B3
Matthias Brugger aa2459
+#define CAVIUM_CPU_PART_OCTX2_95XXN	0x0B4
Matthias Brugger aa2459
+#define CAVIUM_CPU_PART_OCTX2_95XXMM	0x0B5
Matthias Brugger aa2459
+#define CAVIUM_CPU_PART_OCTX2_95XXO	0x0B6
Matthias Brugger aa2459
 
Matthias Brugger aa2459
 #define BRCM_CPU_PART_BRAHMA_B53	0x100
Matthias Brugger aa2459
 #define BRCM_CPU_PART_VULCAN		0x516
Matthias Brugger aa2459
@@ -124,6 +131,12 @@
Matthias Brugger aa2459
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
Matthias Brugger aa2459
 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
Matthias Brugger aa2459
 #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Matthias Brugger aa2459
+#define MIDR_OCTX2_98XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_98XX)
Matthias Brugger aa2459
+#define MIDR_OCTX2_96XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_96XX)
Matthias Brugger aa2459
+#define MIDR_OCTX2_95XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XX)
Matthias Brugger aa2459
+#define MIDR_OCTX2_95XXN MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXN)
Matthias Brugger aa2459
+#define MIDR_OCTX2_95XXMM MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXMM)
Matthias Brugger aa2459
+#define MIDR_OCTX2_95XXO MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXO)
Matthias Brugger aa2459
 #define MIDR_CAVIUM_THUNDERX2 MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX2)
Matthias Brugger aa2459
 #define MIDR_BRAHMA_B53 MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_BRAHMA_B53)
Matthias Brugger aa2459
 #define MIDR_BRCM_VULCAN MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN)
Matthias Brugger aa2459
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
Matthias Brugger aa2459
index b217941713a8..510f47055b91 100644
Matthias Brugger aa2459
--- a/arch/arm64/kernel/cpu_errata.c
Matthias Brugger aa2459
+++ b/arch/arm64/kernel/cpu_errata.c
Matthias Brugger aa2459
@@ -214,6 +214,20 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
Matthias Brugger aa2459
 };
Matthias Brugger aa2459
 #endif
Matthias Brugger aa2459
 
Matthias Brugger aa2459
+#ifdef CONFIG_CAVIUM_ERRATUM_23154
Matthias Brugger aa2459
+const struct midr_range cavium_erratum_23154_cpus[] = {
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_THUNDERX),
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_THUNDERX_81XX),
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_THUNDERX_83XX),
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_OCTX2_98XX),
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_OCTX2_96XX),
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_OCTX2_95XX),
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXN),
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXMM),
Matthias Brugger aa2459
+	MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXO),
Matthias Brugger aa2459
+};
Matthias Brugger aa2459
+#endif
Matthias Brugger aa2459
+
Matthias Brugger aa2459
 #ifdef CONFIG_CAVIUM_ERRATUM_27456
Matthias Brugger aa2459
 const struct midr_range cavium_erratum_27456_cpus[] = {
Matthias Brugger aa2459
 	/* Cavium ThunderX, T88 pass 1.x - 2.1 */
Matthias Brugger aa2459
@@ -425,10 +439,10 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
Matthias Brugger aa2459
 #endif
Matthias Brugger aa2459
 #ifdef CONFIG_CAVIUM_ERRATUM_23154
Matthias Brugger aa2459
 	{
Matthias Brugger aa2459
-	/* Cavium ThunderX, pass 1.x */
Matthias Brugger aa2459
-		.desc = "Cavium erratum 23154",
Matthias Brugger aa2459
+		.desc = "Cavium errata 23154 and 38545",
Matthias Brugger aa2459
 		.capability = ARM64_WORKAROUND_CAVIUM_23154,
Matthias Brugger aa2459
-		ERRATA_MIDR_REV_RANGE(MIDR_THUNDERX, 0, 0, 1),
Matthias Brugger aa2459
+		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
Matthias Brugger aa2459
+		ERRATA_MIDR_RANGE_LIST(cavium_erratum_23154_cpus),
Matthias Brugger aa2459
 	},
Matthias Brugger aa2459
 #endif
Matthias Brugger aa2459
 #ifdef CONFIG_CAVIUM_ERRATUM_27456
Matthias Brugger aa2459
-- 
Matthias Brugger aa2459
2.36.0
Matthias Brugger aa2459