arm64: Add work around for Arm Cortex-A55 Erratum 1024718
authorSuzuki K Poulose <suzuki.poulose@arm.com>
Mon, 26 Mar 2018 14:12:49 +0000 (15:12 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 May 2018 08:08:42 +0000 (10:08 +0200)
commit ece1397cbc89c51914fae1aec729539cfd8bd62b upstream.

Some variants of the Arm Cortex-55 cores (r0p0, r0p1, r1p0) suffer
from an erratum 1024718, which causes incorrect updates when DBM/AP
bits in a page table entry is modified without a break-before-make
sequence. The work around is to skip enabling the hardware DBM feature
on the affected cores. The hardware Access Flag management features
is not affected. There are some other cores suffering from this
errata, which could be added to the midr_list to trigger the work
around.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: ckadabi@codeaurora.org
Reviewed-by: Dave Martin <dave.martin@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/arm64/silicon-errata.txt
arch/arm64/Kconfig
arch/arm64/include/asm/assembler.h
arch/arm64/include/asm/cputype.h
arch/arm64/mm/proc.S

index d11af52427b469808b4e8b8a7383b4fa17d3e549..ac9489fad31b82dbda9e4735bd46f7299ba0a49b 100644 (file)
@@ -54,6 +54,7 @@ stable kernels.
 | ARM            | Cortex-A57      | #852523         | N/A                         |
 | ARM            | Cortex-A57      | #834220         | ARM64_ERRATUM_834220        |
 | ARM            | Cortex-A72      | #853709         | N/A                         |
+| ARM            | Cortex-A55      | #1024718        | ARM64_ERRATUM_1024718       |
 | ARM            | MMU-500         | #841119,#826419 | N/A                         |
 |                |                 |                 |                             |
 | Cavium         | ThunderX ITS    | #22375, #24313  | CAVIUM_ERRATUM_22375        |
index 90e58bbbd858395283b622e6cb6f2a21e8e3f340..d0df3611d1e2c7b0254c14882f95a9719eee5b6b 100644 (file)
@@ -427,6 +427,20 @@ config ARM64_ERRATUM_843419
 
          If unsure, say Y.
 
+config ARM64_ERRATUM_1024718
+       bool "Cortex-A55: 1024718: Update of DBM/AP bits without break before make might result in incorrect update"
+       default y
+       help
+         This option adds work around for Arm Cortex-A55 Erratum 1024718.
+
+         Affected Cortex-A55 cores (r0p0, r0p1, r1p0) could cause incorrect
+         update of the hardware dirty bit when the DBM/AP bits are updated
+         without a break-before-make. The work around is to disable the usage
+         of hardware DBM locally on the affected cores. CPUs not affected by
+         erratum will continue to use the feature.
+
+         If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
        bool "Cavium erratum 22375, 24313"
        default y
index e60375ce0dd20bac40d7fd1d941013e239e0272d..bfcfec3590f6b740b618580f4ca448d5afe930aa 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <asm/asm-offsets.h>
 #include <asm/cpufeature.h>
+#include <asm/cputype.h>
 #include <asm/page.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/ptrace.h>
@@ -435,4 +436,43 @@ alternative_endif
        and     \phys, \pte, #(((1 << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
        .endm
 
+/*
+ * Check the MIDR_EL1 of the current CPU for a given model and a range of
+ * variant/revision. See asm/cputype.h for the macros used below.
+ *
+ *     model:          MIDR_CPU_MODEL of CPU
+ *     rv_min:         Minimum of MIDR_CPU_VAR_REV()
+ *     rv_max:         Maximum of MIDR_CPU_VAR_REV()
+ *     res:            Result register.
+ *     tmp1, tmp2, tmp3: Temporary registers
+ *
+ * Corrupts: res, tmp1, tmp2, tmp3
+ * Returns:  0, if the CPU id doesn't match. Non-zero otherwise
+ */
+       .macro  cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3
+       mrs             \res, midr_el1
+       mov_q           \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK)
+       mov_q           \tmp2, MIDR_CPU_MODEL_MASK
+       and             \tmp3, \res, \tmp2      // Extract model
+       and             \tmp1, \res, \tmp1      // rev & variant
+       mov_q           \tmp2, \model
+       cmp             \tmp3, \tmp2
+       cset            \res, eq
+       cbz             \res, .Ldone\@          // Model matches ?
+
+       .if (\rv_min != 0)                      // Skip min check if rv_min == 0
+       mov_q           \tmp3, \rv_min
+       cmp             \tmp1, \tmp3
+       cset            \res, ge
+       .endif                                  // \rv_min != 0
+       /* Skip rv_max check if rv_min == rv_max && rv_min != 0 */
+       .if ((\rv_min != \rv_max) || \rv_min == 0)
+       mov_q           \tmp2, \rv_max
+       cmp             \tmp1, \tmp2
+       cset            \tmp2, le
+       and             \res, \res, \tmp2
+       .endif
+.Ldone\@:
+       .endm
+
 #endif /* __ASM_ASSEMBLER_H */
index 9ee3038a6b9859bd22d3a94bc60e5bbf6ed70bb5..39d1db68748db3e339d88ee9aa6b85bd4fec221c 100644 (file)
@@ -56,6 +56,9 @@
        (0xf                    << MIDR_ARCHITECTURE_SHIFT) | \
        ((partnum)              << MIDR_PARTNUM_SHIFT))
 
+#define MIDR_CPU_VAR_REV(var, rev) \
+       (((var) << MIDR_VARIANT_SHIFT) | (rev))
+
 #define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
                             MIDR_ARCHITECTURE_MASK)
 
@@ -74,6 +77,7 @@
 
 #define ARM_CPU_PART_AEM_V8            0xD0F
 #define ARM_CPU_PART_FOUNDATION                0xD00
+#define ARM_CPU_PART_CORTEX_A55                0xD05
 #define ARM_CPU_PART_CORTEX_A57                0xD07
 #define ARM_CPU_PART_CORTEX_A72                0xD08
 #define ARM_CPU_PART_CORTEX_A53                0xD03
@@ -89,6 +93,7 @@
 #define BRCM_CPU_PART_VULCAN           0x516
 
 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
 #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
 #define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
index 619da1cbd32baf1c47ecd28b4e1d1ac8ad31d6be..66cce2138f9588289ee055c79273511fecc88e9f 100644 (file)
@@ -425,6 +425,11 @@ ENTRY(__cpu_setup)
        cbz     x9, 2f
        cmp     x9, #2
        b.lt    1f
+#ifdef CONFIG_ARM64_ERRATUM_1024718
+       /* Disable hardware DBM on Cortex-A55 r0p0, r0p1 & r1p0 */
+       cpu_midr_match MIDR_CORTEX_A55, MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(1, 0), x1, x2, x3, x4
+       cbnz    x1, 1f
+#endif
        orr     x10, x10, #TCR_HD               // hardware Dirty flag update
 1:     orr     x10, x10, #TCR_HA               // hardware Access flag update
 2: