Skip to content

Commit b8c3208

Browse files
Suzuki K Poulosegregkh
authored andcommitted
arm64: Add work around for Arm Cortex-A55 Erratum 1024718
commit ece1397 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>
1 parent b8bf4b8 commit b8c3208

5 files changed

Lines changed: 65 additions & 0 deletions

File tree

Documentation/arm64/silicon-errata.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ stable kernels.
5454
| ARM | Cortex-A57 | #852523 | N/A |
5555
| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
5656
| ARM | Cortex-A72 | #853709 | N/A |
57+
| ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 |
5758
| ARM | MMU-500 | #841119,#826419 | N/A |
5859
| | | | |
5960
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |

arch/arm64/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,20 @@ config ARM64_ERRATUM_843419
427427

428428
If unsure, say Y.
429429

430+
config ARM64_ERRATUM_1024718
431+
bool "Cortex-A55: 1024718: Update of DBM/AP bits without break before make might result in incorrect update"
432+
default y
433+
help
434+
This option adds work around for Arm Cortex-A55 Erratum 1024718.
435+
436+
Affected Cortex-A55 cores (r0p0, r0p1, r1p0) could cause incorrect
437+
update of the hardware dirty bit when the DBM/AP bits are updated
438+
without a break-before-make. The work around is to disable the usage
439+
of hardware DBM locally on the affected cores. CPUs not affected by
440+
erratum will continue to use the feature.
441+
442+
If unsure, say Y.
443+
430444
config CAVIUM_ERRATUM_22375
431445
bool "Cavium erratum 22375, 24313"
432446
default y

arch/arm64/include/asm/assembler.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include <asm/asm-offsets.h>
2727
#include <asm/cpufeature.h>
28+
#include <asm/cputype.h>
2829
#include <asm/page.h>
2930
#include <asm/pgtable-hwdef.h>
3031
#include <asm/ptrace.h>
@@ -435,4 +436,43 @@ alternative_endif
435436
and \phys, \pte, #(((1 << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
436437
.endm
437438

439+
/*
440+
* Check the MIDR_EL1 of the current CPU for a given model and a range of
441+
* variant/revision. See asm/cputype.h for the macros used below.
442+
*
443+
* model: MIDR_CPU_MODEL of CPU
444+
* rv_min: Minimum of MIDR_CPU_VAR_REV()
445+
* rv_max: Maximum of MIDR_CPU_VAR_REV()
446+
* res: Result register.
447+
* tmp1, tmp2, tmp3: Temporary registers
448+
*
449+
* Corrupts: res, tmp1, tmp2, tmp3
450+
* Returns: 0, if the CPU id doesn't match. Non-zero otherwise
451+
*/
452+
.macro cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3
453+
mrs \res, midr_el1
454+
mov_q \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK)
455+
mov_q \tmp2, MIDR_CPU_MODEL_MASK
456+
and \tmp3, \res, \tmp2 // Extract model
457+
and \tmp1, \res, \tmp1 // rev & variant
458+
mov_q \tmp2, \model
459+
cmp \tmp3, \tmp2
460+
cset \res, eq
461+
cbz \res, .Ldone\@ // Model matches ?
462+
463+
.if (\rv_min != 0) // Skip min check if rv_min == 0
464+
mov_q \tmp3, \rv_min
465+
cmp \tmp1, \tmp3
466+
cset \res, ge
467+
.endif // \rv_min != 0
468+
/* Skip rv_max check if rv_min == rv_max && rv_min != 0 */
469+
.if ((\rv_min != \rv_max) || \rv_min == 0)
470+
mov_q \tmp2, \rv_max
471+
cmp \tmp1, \tmp2
472+
cset \tmp2, le
473+
and \res, \res, \tmp2
474+
.endif
475+
.Ldone\@:
476+
.endm
477+
438478
#endif /* __ASM_ASSEMBLER_H */

arch/arm64/include/asm/cputype.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
(0xf << MIDR_ARCHITECTURE_SHIFT) | \
5757
((partnum) << MIDR_PARTNUM_SHIFT))
5858

59+
#define MIDR_CPU_VAR_REV(var, rev) \
60+
(((var) << MIDR_VARIANT_SHIFT) | (rev))
61+
5962
#define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
6063
MIDR_ARCHITECTURE_MASK)
6164

@@ -74,6 +77,7 @@
7477

7578
#define ARM_CPU_PART_AEM_V8 0xD0F
7679
#define ARM_CPU_PART_FOUNDATION 0xD00
80+
#define ARM_CPU_PART_CORTEX_A55 0xD05
7781
#define ARM_CPU_PART_CORTEX_A57 0xD07
7882
#define ARM_CPU_PART_CORTEX_A72 0xD08
7983
#define ARM_CPU_PART_CORTEX_A53 0xD03
@@ -89,6 +93,7 @@
8993
#define BRCM_CPU_PART_VULCAN 0x516
9094

9195
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
96+
#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
9297
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
9398
#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
9499
#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)

arch/arm64/mm/proc.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,11 @@ ENTRY(__cpu_setup)
425425
cbz x9, 2f
426426
cmp x9, #2
427427
b.lt 1f
428+
#ifdef CONFIG_ARM64_ERRATUM_1024718
429+
/* Disable hardware DBM on Cortex-A55 r0p0, r0p1 & r1p0 */
430+
cpu_midr_match MIDR_CORTEX_A55, MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(1, 0), x1, x2, x3, x4
431+
cbnz x1, 1f
432+
#endif
428433
orr x10, x10, #TCR_HD // hardware Dirty flag update
429434
1: orr x10, x10, #TCR_HA // hardware Access flag update
430435
2:

0 commit comments

Comments
 (0)