xtensa: limit offsets in __loop_cache_{all,page}
authorMax Filippov <jcmvbkbc@gmail.com>
Sat, 11 Aug 2018 03:43:48 +0000 (20:43 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Sep 2018 17:55:58 +0000 (19:55 +0200)
commit be75de25251f7cf3e399ca1f584716a95510d24a upstream.

When building kernel for xtensa cores with big cache lines (e.g. 128
bytes or more) __loop_cache_all and __loop_cache_page may generate
assembly instructions with immediate fields that are too big. This
results in the following build errors:

  arch/xtensa/mm/misc.S: Assembler messages:
  arch/xtensa/mm/misc.S:464: Error: operand 2 of 'diwbi' has invalid value '256'
  arch/xtensa/mm/misc.S:464: Error: operand 2 of 'diwbi' has invalid value '384'
  arch/xtensa/kernel/head.S: Assembler messages:
  arch/xtensa/kernel/head.S:172: Error: operand 2 of 'diu' has invalid value '256'
  arch/xtensa/kernel/head.S:172: Error: operand 2 of 'diu' has invalid value '384'
  arch/xtensa/kernel/head.S:176: Error: operand 2 of 'iiu' has invalid value '256'
  arch/xtensa/kernel/head.S:176: Error: operand 2 of 'iiu' has invalid value '384'
  arch/xtensa/kernel/head.S:255: Error: operand 2 of 'diwb' has invalid value '256'
  arch/xtensa/kernel/head.S:255: Error: operand 2 of 'diwb' has invalid value '384'

Add parameter max_immed to these macros and use it to limit values of
immediate operands. Extract common code of these macros into the new
macro __loop_cache_unroll.

Cc: stable@vger.kernel.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/xtensa/include/asm/cacheasm.h

index 2041abb10a2352a4b1f4323f3e1f0d9bdfff36ec..2c73b45712261688e07c5984a8681f57335abcca 100644 (file)
  *
  */
 
-       .macro  __loop_cache_all ar at insn size line_width
 
-       movi    \ar, 0
+       .macro  __loop_cache_unroll ar at insn size line_width max_immed
+
+       .if     (1 << (\line_width)) > (\max_immed)
+       .set    _reps, 1
+       .elseif (2 << (\line_width)) > (\max_immed)
+       .set    _reps, 2
+       .else
+       .set    _reps, 4
+       .endif
+
+       __loopi \ar, \at, \size, (_reps << (\line_width))
+       .set    _index, 0
+       .rep    _reps
+       \insn   \ar, _index << (\line_width)
+       .set    _index, _index + 1
+       .endr
+       __endla \ar, \at, _reps << (\line_width)
+
+       .endm
+
 
-       __loopi \ar, \at, \size, (4 << (\line_width))
-       \insn   \ar, 0 << (\line_width)
-       \insn   \ar, 1 << (\line_width)
-       \insn   \ar, 2 << (\line_width)
-       \insn   \ar, 3 << (\line_width)
-       __endla \ar, \at, 4 << (\line_width)
+       .macro  __loop_cache_all ar at insn size line_width max_immed
+
+       movi    \ar, 0
+       __loop_cache_unroll \ar, \at, \insn, \size, \line_width, \max_immed
 
        .endm
 
        .endm
 
 
-       .macro  __loop_cache_page ar at insn line_width
+       .macro  __loop_cache_page ar at insn line_width max_immed
 
-       __loopi \ar, \at, PAGE_SIZE, 4 << (\line_width)
-       \insn   \ar, 0 << (\line_width)
-       \insn   \ar, 1 << (\line_width)
-       \insn   \ar, 2 << (\line_width)
-       \insn   \ar, 3 << (\line_width)
-       __endla \ar, \at, 4 << (\line_width)
+       __loop_cache_unroll \ar, \at, \insn, PAGE_SIZE, \line_width, \max_immed
 
        .endm
 
@@ -72,7 +83,8 @@
        .macro  ___unlock_dcache_all ar at
 
 #if XCHAL_DCACHE_LINE_LOCKABLE && XCHAL_DCACHE_SIZE
-       __loop_cache_all \ar \at diu XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_all \ar \at diu XCHAL_DCACHE_SIZE \
+               XCHAL_DCACHE_LINEWIDTH 240
 #endif
 
        .endm
@@ -81,7 +93,8 @@
        .macro  ___unlock_icache_all ar at
 
 #if XCHAL_ICACHE_LINE_LOCKABLE && XCHAL_ICACHE_SIZE
-       __loop_cache_all \ar \at iiu XCHAL_ICACHE_SIZE XCHAL_ICACHE_LINEWIDTH
+       __loop_cache_all \ar \at iiu XCHAL_ICACHE_SIZE \
+               XCHAL_ICACHE_LINEWIDTH 240
 #endif
 
        .endm
        .macro  ___flush_invalidate_dcache_all ar at
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_all \ar \at diwbi XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_all \ar \at diwbi XCHAL_DCACHE_SIZE \
+               XCHAL_DCACHE_LINEWIDTH 240
 #endif
 
        .endm
        .macro  ___flush_dcache_all ar at
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_all \ar \at diwb XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_all \ar \at diwb XCHAL_DCACHE_SIZE \
+               XCHAL_DCACHE_LINEWIDTH 240
 #endif
 
        .endm
 
 #if XCHAL_DCACHE_SIZE
        __loop_cache_all \ar \at dii __stringify(DCACHE_WAY_SIZE) \
-                        XCHAL_DCACHE_LINEWIDTH
+                        XCHAL_DCACHE_LINEWIDTH 1020
 #endif
 
        .endm
 
 #if XCHAL_ICACHE_SIZE
        __loop_cache_all \ar \at iii __stringify(ICACHE_WAY_SIZE) \
-                        XCHAL_ICACHE_LINEWIDTH
+                        XCHAL_ICACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro  ___flush_invalidate_dcache_page ar as
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_page \ar \as dhwbi XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_page \ar \as dhwbi XCHAL_DCACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro ___flush_dcache_page ar as
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_page \ar \as dhwb XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_page \ar \as dhwb XCHAL_DCACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro  ___invalidate_dcache_page ar as
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_page \ar \as dhi XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_page \ar \as dhi XCHAL_DCACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro  ___invalidate_icache_page ar as
 
 #if XCHAL_ICACHE_SIZE
-       __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH
+       __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH 1020
 #endif
 
        .endm