Skip to content

Commit 33309ec

Browse files
committed
arm64: Fix minor issues with the dcache_by_line_op macro
The dcache_by_line_op macro suffers from a couple of small problems: First, the GAS directives that are currently being used rely on assembler behavior that is not documented, and probably not guaranteed to produce the correct behavior going forward. As a result, we end up with some undefined symbols in cache.o: $ nm arch/arm64/mm/cache.o ... U civac ... U cvac U cvap U cvau This is due to the fact that the comparisons used to select the operation type in the dcache_by_line_op macro are comparing symbols not strings, and even though it seems that GAS is doing the right thing here (undefined symbols by the same name are equal to each other), it seems unwise to rely on this. Second, when patching in a DC CVAP instruction on CPUs that support it, the fallback path consists of a DC CVAU instruction which may be affected by CPU errata that require ARM64_WORKAROUND_CLEAN_CACHE. Solve these issues by unrolling the various maintenance routines and using the conditional directives that are documented as operating on strings. To avoid the complexity of nested alternatives, we move the DC CVAP patching to __clean_dcache_area_pop, falling back to a branch to __clean_dcache_area_poc if DCPOP is not supported by the CPU. Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Suggested-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
1 parent 2a9cee5 commit 33309ec

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

arch/arm64/include/asm/assembler.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -392,27 +392,33 @@ alternative_endif
392392
* size: size of the region
393393
* Corrupts: kaddr, size, tmp1, tmp2
394394
*/
395+
.macro __dcache_op_workaround_clean_cache, op, kaddr
396+
alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE
397+
dc \op, \kaddr
398+
alternative_else
399+
dc civac, \kaddr
400+
alternative_endif
401+
.endm
402+
395403
.macro dcache_by_line_op op, domain, kaddr, size, tmp1, tmp2
396404
dcache_line_size \tmp1, \tmp2
397405
add \size, \kaddr, \size
398406
sub \tmp2, \tmp1, #1
399407
bic \kaddr, \kaddr, \tmp2
400408
9998:
401-
.if (\op == cvau || \op == cvac)
402-
alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE
403-
dc \op, \kaddr
404-
alternative_else
405-
dc civac, \kaddr
406-
alternative_endif
407-
.elseif (\op == cvap)
408-
alternative_if ARM64_HAS_DCPOP
409-
sys 3, c7, c12, 1, \kaddr // dc cvap
410-
alternative_else
411-
dc cvac, \kaddr
412-
alternative_endif
409+
.ifc \op, cvau
410+
__dcache_op_workaround_clean_cache \op, \kaddr
411+
.else
412+
.ifc \op, cvac
413+
__dcache_op_workaround_clean_cache \op, \kaddr
414+
.else
415+
.ifc \op, cvap
416+
sys 3, c7, c12, 1, \kaddr // dc cvap
413417
.else
414418
dc \op, \kaddr
415419
.endif
420+
.endif
421+
.endif
416422
add \kaddr, \kaddr, \tmp1
417423
cmp \kaddr, \size
418424
b.lo 9998b

arch/arm64/mm/cache.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ ENDPROC(__dma_clean_area)
212212
* - size - size in question
213213
*/
214214
ENTRY(__clean_dcache_area_pop)
215+
alternative_if_not ARM64_HAS_DCPOP
216+
b __clean_dcache_area_poc
217+
alternative_else_nop_endif
215218
dcache_by_line_op cvap, sy, x0, x1, x2, x3
216219
ret
217220
ENDPIPROC(__clean_dcache_area_pop)

0 commit comments

Comments
 (0)