Skip to content

Commit 348f043

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 <[email protected]> Cc: [email protected] Reviewed-by: Dave Martin <[email protected]> Signed-off-by: Suzuki K Poulose <[email protected]> Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Suzuki K Poulose <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 45eecfb commit 348f043

File tree

4 files changed

+70
-0
lines changed

4 files changed

+70
-0
lines changed

arch/arm64/Kconfig

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

376376
If unsure, say Y.
377377

378+
config ARM64_ERRATUM_1024718
379+
bool "Cortex-A55: 1024718: Update of DBM/AP bits without break before make might result in incorrect update"
380+
default y
381+
help
382+
This option adds work around for Arm Cortex-A55 Erratum 1024718.
383+
384+
Affected Cortex-A55 cores (r0p0, r0p1, r1p0) could cause incorrect
385+
update of the hardware dirty bit when the DBM/AP bits are updated
386+
without a break-before-make. The work around is to disable the usage
387+
of hardware DBM locally on the affected cores. CPUs not affected by
388+
erratum will continue to use the feature.
389+
390+
If unsure, say Y.
391+
378392
config CAVIUM_ERRATUM_22375
379393
bool "Cavium erratum 22375, 24313"
380394
default y

arch/arm64/include/asm/assembler.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#ifndef __ASM_ASSEMBLER_H
2424
#define __ASM_ASSEMBLER_H
2525

26+
#include <asm/cputype.h>
2627
#include <asm/ptrace.h>
2728
#include <asm/thread_info.h>
2829

@@ -224,4 +225,43 @@ lr .req x30 // link register
224225
movk \reg, :abs_g0_nc:\val
225226
.endm
226227

228+
/*
229+
* Check the MIDR_EL1 of the current CPU for a given model and a range of
230+
* variant/revision. See asm/cputype.h for the macros used below.
231+
*
232+
* model: MIDR_CPU_PART of CPU
233+
* rv_min: Minimum of MIDR_CPU_VAR_REV()
234+
* rv_max: Maximum of MIDR_CPU_VAR_REV()
235+
* res: Result register.
236+
* tmp1, tmp2, tmp3: Temporary registers
237+
*
238+
* Corrupts: res, tmp1, tmp2, tmp3
239+
* Returns: 0, if the CPU id doesn't match. Non-zero otherwise
240+
*/
241+
.macro cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3
242+
mrs \res, midr_el1
243+
mov_q \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK)
244+
mov_q \tmp2, MIDR_CPU_PART_MASK
245+
and \tmp3, \res, \tmp2 // Extract model
246+
and \tmp1, \res, \tmp1 // rev & variant
247+
mov_q \tmp2, \model
248+
cmp \tmp3, \tmp2
249+
cset \res, eq
250+
cbz \res, .Ldone\@ // Model matches ?
251+
252+
.if (\rv_min != 0) // Skip min check if rv_min == 0
253+
mov_q \tmp3, \rv_min
254+
cmp \tmp1, \tmp3
255+
cset \res, ge
256+
.endif // \rv_min != 0
257+
/* Skip rv_max check if rv_min == rv_max && rv_min != 0 */
258+
.if ((\rv_min != \rv_max) || \rv_min == 0)
259+
mov_q \tmp2, \rv_max
260+
cmp \tmp1, \tmp2
261+
cset \tmp2, le
262+
and \res, \res, \tmp2
263+
.endif
264+
.Ldone\@:
265+
.endm
266+
227267
#endif /* __ASM_ASSEMBLER_H */

arch/arm64/include/asm/cputype.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@
5757
#define MIDR_IMPLEMENTOR(midr) \
5858
(((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
5959

60+
#define MIDR_CPU_VAR_REV(var, rev) \
61+
(((var) << MIDR_VARIANT_SHIFT) | (rev))
62+
63+
#define MIDR_CPU_PART_MASK \
64+
(MIDR_IMPLEMENTOR_MASK | \
65+
MIDR_ARCHITECTURE_MASK | \
66+
MIDR_PARTNUM_MASK)
67+
6068
#define MIDR_CPU_PART(imp, partnum) \
6169
(((imp) << MIDR_IMPLEMENTOR_SHIFT) | \
6270
(0xf << MIDR_ARCHITECTURE_SHIFT) | \
@@ -70,11 +78,14 @@
7078
#define ARM_CPU_PART_FOUNDATION 0xD00
7179
#define ARM_CPU_PART_CORTEX_A57 0xD07
7280
#define ARM_CPU_PART_CORTEX_A53 0xD03
81+
#define ARM_CPU_PART_CORTEX_A55 0xD05
7382

7483
#define APM_CPU_PART_POTENZA 0x000
7584

7685
#define CAVIUM_CPU_PART_THUNDERX 0x0A1
7786

87+
#define MIDR_CORTEX_A55 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
88+
7889
#ifndef __ASSEMBLY__
7990

8091
/*

arch/arm64/mm/proc.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,11 @@ ENTRY(__cpu_setup)
221221
cbz x9, 2f
222222
cmp x9, #2
223223
b.lt 1f
224+
#ifdef CONFIG_ARM64_ERRATUM_1024718
225+
/* Disable hardware DBM on Cortex-A55 r0p0, r0p1 & r1p0 */
226+
cpu_midr_match MIDR_CORTEX_A55, MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(1, 0), x1, x2, x3, x4
227+
cbnz x1, 1f
228+
#endif
224229
orr x10, x10, #TCR_HD // hardware Dirty flag update
225230
1: orr x10, x10, #TCR_HA // hardware Access flag update
226231
2:

0 commit comments

Comments
 (0)