summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2017-12-10 00:18:47 -0500
committerMax Filippov <jcmvbkbc@gmail.com>2017-12-10 17:48:53 -0500
commit0013aceb307482ba83a5b6a29f6ba1791be0d32b (patch)
tree63f0312a68e62d0f52212ce7bdab9d75e4ee6ead
parent2da03d4114b2587f0e8e45f4862074e34daee64e (diff)
xtensa: clean up fixups in assembly code
Remove duplicate definitions of EX() and similar TRY/CATCH and SRC/DST macros from assembly sources and put single definition into asm/asmmacro.h Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r--arch/xtensa/include/asm/asmmacro.h7
-rw-r--r--arch/xtensa/kernel/entry.S33
-rw-r--r--arch/xtensa/lib/checksum.S74
-rw-r--r--arch/xtensa/lib/memset.S36
-rw-r--r--arch/xtensa/lib/strncpy_user.S52
-rw-r--r--arch/xtensa/lib/strnlen_user.S19
-rw-r--r--arch/xtensa/lib/usercopy.S106
7 files changed, 133 insertions, 194 deletions
diff --git a/arch/xtensa/include/asm/asmmacro.h b/arch/xtensa/include/asm/asmmacro.h
index 746dcc8b5abc..d2a4415a4c08 100644
--- a/arch/xtensa/include/asm/asmmacro.h
+++ b/arch/xtensa/include/asm/asmmacro.h
@@ -150,5 +150,12 @@
150 __endl \ar \as 150 __endl \ar \as
151 .endm 151 .endm
152 152
153/* Load or store instructions that may cause exceptions use the EX macro. */
154
155#define EX(handler) \
156 .section __ex_table, "a"; \
157 .word 97f, handler; \
158 .previous \
15997:
153 160
154#endif /* _XTENSA_ASMMACRO_H */ 161#endif /* _XTENSA_ASMMACRO_H */
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 5a2110bb5902..a27a9a65635b 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -14,6 +14,7 @@
14 14
15#include <linux/linkage.h> 15#include <linux/linkage.h>
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/asmmacro.h>
17#include <asm/processor.h> 18#include <asm/processor.h>
18#include <asm/coprocessor.h> 19#include <asm/coprocessor.h>
19#include <asm/thread_info.h> 20#include <asm/thread_info.h>
@@ -1094,35 +1095,12 @@ ENDPROC(fast_syscall_unrecoverable)
1094 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception 1095 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1095 * 1096 *
1096 * Note: we don't have to save a2; a2 holds the return value 1097 * Note: we don't have to save a2; a2 holds the return value
1097 *
1098 * We use the two macros TRY and CATCH:
1099 *
1100 * TRY adds an entry to the __ex_table fixup table for the immediately
1101 * following instruction.
1102 *
1103 * CATCH catches any exception that occurred at one of the preceding TRY
1104 * statements and continues from there
1105 *
1106 * Usage TRY l32i a0, a1, 0
1107 * <other code>
1108 * done: rfe
1109 * CATCH <set return code>
1110 * j done
1111 */ 1098 */
1112 1099
1113 .literal_position 1100 .literal_position
1114 1101
1115#ifdef CONFIG_FAST_SYSCALL_XTENSA 1102#ifdef CONFIG_FAST_SYSCALL_XTENSA
1116 1103
1117#define TRY \
1118 .section __ex_table, "a"; \
1119 .word 66f, 67f; \
1120 .text; \
112166:
1122
1123#define CATCH \
112467:
1125
1126ENTRY(fast_syscall_xtensa) 1104ENTRY(fast_syscall_xtensa)
1127 1105
1128 s32i a7, a2, PT_AREG7 # we need an additional register 1106 s32i a7, a2, PT_AREG7 # we need an additional register
@@ -1136,9 +1114,9 @@ ENTRY(fast_syscall_xtensa)
1136 1114
1137.Lswp: /* Atomic compare and swap */ 1115.Lswp: /* Atomic compare and swap */
1138 1116
1139TRY l32i a0, a3, 0 # read old value 1117EX(.Leac) l32i a0, a3, 0 # read old value
1140 bne a0, a4, 1f # same as old value? jump 1118 bne a0, a4, 1f # same as old value? jump
1141TRY s32i a5, a3, 0 # different, modify value 1119EX(.Leac) s32i a5, a3, 0 # different, modify value
1142 l32i a7, a2, PT_AREG7 # restore a7 1120 l32i a7, a2, PT_AREG7 # restore a7
1143 l32i a0, a2, PT_AREG0 # restore a0 1121 l32i a0, a2, PT_AREG0 # restore a0
1144 movi a2, 1 # and return 1 1122 movi a2, 1 # and return 1
@@ -1151,12 +1129,12 @@ TRY s32i a5, a3, 0 # different, modify value
1151 1129
1152.Lnswp: /* Atomic set, add, and exg_add. */ 1130.Lnswp: /* Atomic set, add, and exg_add. */
1153 1131
1154TRY l32i a7, a3, 0 # orig 1132EX(.Leac) l32i a7, a3, 0 # orig
1155 addi a6, a6, -SYS_XTENSA_ATOMIC_SET 1133 addi a6, a6, -SYS_XTENSA_ATOMIC_SET
1156 add a0, a4, a7 # + arg 1134 add a0, a4, a7 # + arg
1157 moveqz a0, a4, a6 # set 1135 moveqz a0, a4, a6 # set
1158 addi a6, a6, SYS_XTENSA_ATOMIC_SET 1136 addi a6, a6, SYS_XTENSA_ATOMIC_SET
1159TRY s32i a0, a3, 0 # write new value 1137EX(.Leac) s32i a0, a3, 0 # write new value
1160 1138
1161 mov a0, a2 1139 mov a0, a2
1162 mov a2, a7 1140 mov a2, a7
@@ -1164,7 +1142,6 @@ TRY s32i a0, a3, 0 # write new value
1164 l32i a0, a0, PT_AREG0 # restore a0 1142 l32i a0, a0, PT_AREG0 # restore a0
1165 rfe 1143 rfe
1166 1144
1167CATCH
1168.Leac: l32i a7, a2, PT_AREG7 # restore a7 1145.Leac: l32i a7, a2, PT_AREG7 # restore a7
1169 l32i a0, a2, PT_AREG0 # restore a0 1146 l32i a0, a2, PT_AREG0 # restore a0
1170 movi a2, -EFAULT 1147 movi a2, -EFAULT
diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S
index 4eb573d2720e..528fe0dd9339 100644
--- a/arch/xtensa/lib/checksum.S
+++ b/arch/xtensa/lib/checksum.S
@@ -14,9 +14,10 @@
14 * 2 of the License, or (at your option) any later version. 14 * 2 of the License, or (at your option) any later version.
15 */ 15 */
16 16
17#include <asm/errno.h> 17#include <linux/errno.h>
18#include <linux/linkage.h> 18#include <linux/linkage.h>
19#include <variant/core.h> 19#include <variant/core.h>
20#include <asm/asmmacro.h>
20 21
21/* 22/*
22 * computes a partial checksum, e.g. for TCP/UDP fragments 23 * computes a partial checksum, e.g. for TCP/UDP fragments
@@ -175,23 +176,8 @@ ENDPROC(csum_partial)
175 176
176/* 177/*
177 * Copy from ds while checksumming, otherwise like csum_partial 178 * Copy from ds while checksumming, otherwise like csum_partial
178 *
179 * The macros SRC and DST specify the type of access for the instruction.
180 * thus we can call a custom exception handler for each access type.
181 */ 179 */
182 180
183#define SRC(y...) \
184 9999: y; \
185 .section __ex_table, "a"; \
186 .long 9999b, 6001f ; \
187 .previous
188
189#define DST(y...) \
190 9999: y; \
191 .section __ex_table, "a"; \
192 .long 9999b, 6002f ; \
193 .previous
194
195/* 181/*
196unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, 182unsigned int csum_partial_copy_generic (const char *src, char *dst, int len,
197 int sum, int *src_err_ptr, int *dst_err_ptr) 183 int sum, int *src_err_ptr, int *dst_err_ptr)
@@ -244,28 +230,28 @@ ENTRY(csum_partial_copy_generic)
244 add a10, a10, a2 /* a10 = end of last 32-byte src chunk */ 230 add a10, a10, a2 /* a10 = end of last 32-byte src chunk */
245.Loop5: 231.Loop5:
246#endif 232#endif
247SRC( l32i a9, a2, 0 ) 233EX(10f) l32i a9, a2, 0
248SRC( l32i a8, a2, 4 ) 234EX(10f) l32i a8, a2, 4
249DST( s32i a9, a3, 0 ) 235EX(11f) s32i a9, a3, 0
250DST( s32i a8, a3, 4 ) 236EX(11f) s32i a8, a3, 4
251 ONES_ADD(a5, a9) 237 ONES_ADD(a5, a9)
252 ONES_ADD(a5, a8) 238 ONES_ADD(a5, a8)
253SRC( l32i a9, a2, 8 ) 239EX(10f) l32i a9, a2, 8
254SRC( l32i a8, a2, 12 ) 240EX(10f) l32i a8, a2, 12
255DST( s32i a9, a3, 8 ) 241EX(11f) s32i a9, a3, 8
256DST( s32i a8, a3, 12 ) 242EX(11f) s32i a8, a3, 12
257 ONES_ADD(a5, a9) 243 ONES_ADD(a5, a9)
258 ONES_ADD(a5, a8) 244 ONES_ADD(a5, a8)
259SRC( l32i a9, a2, 16 ) 245EX(10f) l32i a9, a2, 16
260SRC( l32i a8, a2, 20 ) 246EX(10f) l32i a8, a2, 20
261DST( s32i a9, a3, 16 ) 247EX(11f) s32i a9, a3, 16
262DST( s32i a8, a3, 20 ) 248EX(11f) s32i a8, a3, 20
263 ONES_ADD(a5, a9) 249 ONES_ADD(a5, a9)
264 ONES_ADD(a5, a8) 250 ONES_ADD(a5, a8)
265SRC( l32i a9, a2, 24 ) 251EX(10f) l32i a9, a2, 24
266SRC( l32i a8, a2, 28 ) 252EX(10f) l32i a8, a2, 28
267DST( s32i a9, a3, 24 ) 253EX(11f) s32i a9, a3, 24
268DST( s32i a8, a3, 28 ) 254EX(11f) s32i a8, a3, 28
269 ONES_ADD(a5, a9) 255 ONES_ADD(a5, a9)
270 ONES_ADD(a5, a8) 256 ONES_ADD(a5, a8)
271 addi a2, a2, 32 257 addi a2, a2, 32
@@ -284,8 +270,8 @@ DST( s32i a8, a3, 28 )
284 add a10, a10, a2 /* a10 = end of last 4-byte src chunk */ 270 add a10, a10, a2 /* a10 = end of last 4-byte src chunk */
285.Loop6: 271.Loop6:
286#endif 272#endif
287SRC( l32i a9, a2, 0 ) 273EX(10f) l32i a9, a2, 0
288DST( s32i a9, a3, 0 ) 274EX(11f) s32i a9, a3, 0
289 ONES_ADD(a5, a9) 275 ONES_ADD(a5, a9)
290 addi a2, a2, 4 276 addi a2, a2, 4
291 addi a3, a3, 4 277 addi a3, a3, 4
@@ -315,8 +301,8 @@ DST( s32i a9, a3, 0 )
315 add a10, a10, a2 /* a10 = end of last 2-byte src chunk */ 301 add a10, a10, a2 /* a10 = end of last 2-byte src chunk */
316.Loop7: 302.Loop7:
317#endif 303#endif
318SRC( l16ui a9, a2, 0 ) 304EX(10f) l16ui a9, a2, 0
319DST( s16i a9, a3, 0 ) 305EX(11f) s16i a9, a3, 0
320 ONES_ADD(a5, a9) 306 ONES_ADD(a5, a9)
321 addi a2, a2, 2 307 addi a2, a2, 2
322 addi a3, a3, 2 308 addi a3, a3, 2
@@ -326,8 +312,8 @@ DST( s16i a9, a3, 0 )
3264: 3124:
327 /* This section processes a possible trailing odd byte. */ 313 /* This section processes a possible trailing odd byte. */
328 _bbci.l a4, 0, 8f /* 1-byte chunk */ 314 _bbci.l a4, 0, 8f /* 1-byte chunk */
329SRC( l8ui a9, a2, 0 ) 315EX(10f) l8ui a9, a2, 0
330DST( s8i a9, a3, 0 ) 316EX(11f) s8i a9, a3, 0
331#ifdef __XTENSA_EB__ 317#ifdef __XTENSA_EB__
332 slli a9, a9, 8 /* shift byte to bits 8..15 */ 318 slli a9, a9, 8 /* shift byte to bits 8..15 */
333#endif 319#endif
@@ -350,10 +336,10 @@ DST( s8i a9, a3, 0 )
350 add a10, a10, a2 /* a10 = end of last odd-aligned, 2-byte src chunk */ 336 add a10, a10, a2 /* a10 = end of last odd-aligned, 2-byte src chunk */
351.Loop8: 337.Loop8:
352#endif 338#endif
353SRC( l8ui a9, a2, 0 ) 339EX(10f) l8ui a9, a2, 0
354SRC( l8ui a8, a2, 1 ) 340EX(10f) l8ui a8, a2, 1
355DST( s8i a9, a3, 0 ) 341EX(11f) s8i a9, a3, 0
356DST( s8i a8, a3, 1 ) 342EX(11f) s8i a8, a3, 1
357#ifdef __XTENSA_EB__ 343#ifdef __XTENSA_EB__
358 slli a9, a9, 8 /* combine into a single 16-bit value */ 344 slli a9, a9, 8 /* combine into a single 16-bit value */
359#else /* for checksum computation */ 345#else /* for checksum computation */
@@ -381,7 +367,7 @@ ENDPROC(csum_partial_copy_generic)
381 a12 = original dst for exception handling 367 a12 = original dst for exception handling
382*/ 368*/
383 369
3846001: 37010:
385 _movi a2, -EFAULT 371 _movi a2, -EFAULT
386 s32i a2, a6, 0 /* src_err_ptr */ 372 s32i a2, a6, 0 /* src_err_ptr */
387 373
@@ -403,7 +389,7 @@ ENDPROC(csum_partial_copy_generic)
4032: 3892:
404 retw 390 retw
405 391
4066002: 39211:
407 movi a2, -EFAULT 393 movi a2, -EFAULT
408 s32i a2, a7, 0 /* dst_err_ptr */ 394 s32i a2, a7, 0 /* dst_err_ptr */
409 movi a2, 0 395 movi a2, 0
diff --git a/arch/xtensa/lib/memset.S b/arch/xtensa/lib/memset.S
index 10b8c400f175..7a724edaf4f1 100644
--- a/arch/xtensa/lib/memset.S
+++ b/arch/xtensa/lib/memset.S
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <variant/core.h> 14#include <variant/core.h>
15#include <asm/asmmacro.h>
15 16
16/* 17/*
17 * void *memset(void *dst, int c, size_t length) 18 * void *memset(void *dst, int c, size_t length)
@@ -28,15 +29,6 @@
28 * the alignment labels). 29 * the alignment labels).
29 */ 30 */
30 31
31/* Load or store instructions that may cause exceptions use the EX macro. */
32
33#define EX(insn,reg1,reg2,offset,handler) \
349: insn reg1, reg2, offset; \
35 .section __ex_table, "a"; \
36 .word 9b, handler; \
37 .previous
38
39
40.text 32.text
41.align 4 33.align 4
42.global memset 34.global memset
@@ -73,10 +65,10 @@ memset:
73 add a6, a6, a5 # a6 = end of last 16B chunk 65 add a6, a6, a5 # a6 = end of last 16B chunk
74#endif /* !XCHAL_HAVE_LOOPS */ 66#endif /* !XCHAL_HAVE_LOOPS */
75.Loop1: 67.Loop1:
76 EX(s32i, a3, a5, 0, memset_fixup) 68EX(10f) s32i a3, a5, 0
77 EX(s32i, a3, a5, 4, memset_fixup) 69EX(10f) s32i a3, a5, 4
78 EX(s32i, a3, a5, 8, memset_fixup) 70EX(10f) s32i a3, a5, 8
79 EX(s32i, a3, a5, 12, memset_fixup) 71EX(10f) s32i a3, a5, 12
80 addi a5, a5, 16 72 addi a5, a5, 16
81#if !XCHAL_HAVE_LOOPS 73#if !XCHAL_HAVE_LOOPS
82 blt a5, a6, .Loop1 74 blt a5, a6, .Loop1
@@ -84,23 +76,23 @@ memset:
84.Loop1done: 76.Loop1done:
85 bbci.l a4, 3, .L2 77 bbci.l a4, 3, .L2
86 # set 8 bytes 78 # set 8 bytes
87 EX(s32i, a3, a5, 0, memset_fixup) 79EX(10f) s32i a3, a5, 0
88 EX(s32i, a3, a5, 4, memset_fixup) 80EX(10f) s32i a3, a5, 4
89 addi a5, a5, 8 81 addi a5, a5, 8
90.L2: 82.L2:
91 bbci.l a4, 2, .L3 83 bbci.l a4, 2, .L3
92 # set 4 bytes 84 # set 4 bytes
93 EX(s32i, a3, a5, 0, memset_fixup) 85EX(10f) s32i a3, a5, 0
94 addi a5, a5, 4 86 addi a5, a5, 4
95.L3: 87.L3:
96 bbci.l a4, 1, .L4 88 bbci.l a4, 1, .L4
97 # set 2 bytes 89 # set 2 bytes
98 EX(s16i, a3, a5, 0, memset_fixup) 90EX(10f) s16i a3, a5, 0
99 addi a5, a5, 2 91 addi a5, a5, 2
100.L4: 92.L4:
101 bbci.l a4, 0, .L5 93 bbci.l a4, 0, .L5
102 # set 1 byte 94 # set 1 byte
103 EX(s8i, a3, a5, 0, memset_fixup) 95EX(10f) s8i a3, a5, 0
104.L5: 96.L5:
105.Lret1: 97.Lret1:
106 retw 98 retw
@@ -114,7 +106,7 @@ memset:
114 bbci.l a5, 0, .L20 # branch if dst alignment half-aligned 106 bbci.l a5, 0, .L20 # branch if dst alignment half-aligned
115 # dst is only byte aligned 107 # dst is only byte aligned
116 # set 1 byte 108 # set 1 byte
117 EX(s8i, a3, a5, 0, memset_fixup) 109EX(10f) s8i a3, a5, 0
118 addi a5, a5, 1 110 addi a5, a5, 1
119 addi a4, a4, -1 111 addi a4, a4, -1
120 # now retest if dst aligned 112 # now retest if dst aligned
@@ -122,7 +114,7 @@ memset:
122.L20: 114.L20:
123 # dst half-aligned 115 # dst half-aligned
124 # set 2 bytes 116 # set 2 bytes
125 EX(s16i, a3, a5, 0, memset_fixup) 117EX(10f) s16i a3, a5, 0
126 addi a5, a5, 2 118 addi a5, a5, 2
127 addi a4, a4, -2 119 addi a4, a4, -2
128 j .L0 # dst is now aligned, return to main algorithm 120 j .L0 # dst is now aligned, return to main algorithm
@@ -141,7 +133,7 @@ memset:
141 add a6, a5, a4 # a6 = ending address 133 add a6, a5, a4 # a6 = ending address
142#endif /* !XCHAL_HAVE_LOOPS */ 134#endif /* !XCHAL_HAVE_LOOPS */
143.Lbyteloop: 135.Lbyteloop:
144 EX(s8i, a3, a5, 0, memset_fixup) 136EX(10f) s8i a3, a5, 0
145 addi a5, a5, 1 137 addi a5, a5, 1
146#if !XCHAL_HAVE_LOOPS 138#if !XCHAL_HAVE_LOOPS
147 blt a5, a6, .Lbyteloop 139 blt a5, a6, .Lbyteloop
@@ -155,6 +147,6 @@ memset:
155 147
156/* We return zero if a failure occurred. */ 148/* We return zero if a failure occurred. */
157 149
158memset_fixup: 15010:
159 movi a2, 0 151 movi a2, 0
160 retw 152 retw
diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S
index 1ad0ecf45368..827e1b393f3f 100644
--- a/arch/xtensa/lib/strncpy_user.S
+++ b/arch/xtensa/lib/strncpy_user.S
@@ -11,16 +11,9 @@
11 * Copyright (C) 2002 Tensilica Inc. 11 * Copyright (C) 2002 Tensilica Inc.
12 */ 12 */
13 13
14#include <variant/core.h>
15#include <linux/errno.h> 14#include <linux/errno.h>
16 15#include <variant/core.h>
17/* Load or store instructions that may cause exceptions use the EX macro. */ 16#include <asm/asmmacro.h>
18
19#define EX(insn,reg1,reg2,offset,handler) \
209: insn reg1, reg2, offset; \
21 .section __ex_table, "a"; \
22 .word 9b, handler; \
23 .previous
24 17
25/* 18/*
26 * char *__strncpy_user(char *dst, const char *src, size_t len) 19 * char *__strncpy_user(char *dst, const char *src, size_t len)
@@ -75,9 +68,9 @@ __strncpy_user:
75 j .Ldstunaligned 68 j .Ldstunaligned
76 69
77.Lsrc1mod2: # src address is odd 70.Lsrc1mod2: # src address is odd
78 EX(l8ui, a9, a3, 0, fixup_l) # get byte 0 71EX(11f) l8ui a9, a3, 0 # get byte 0
79 addi a3, a3, 1 # advance src pointer 72 addi a3, a3, 1 # advance src pointer
80 EX(s8i, a9, a11, 0, fixup_s) # store byte 0 73EX(10f) s8i a9, a11, 0 # store byte 0
81 beqz a9, .Lret # if byte 0 is zero 74 beqz a9, .Lret # if byte 0 is zero
82 addi a11, a11, 1 # advance dst pointer 75 addi a11, a11, 1 # advance dst pointer
83 addi a4, a4, -1 # decrement len 76 addi a4, a4, -1 # decrement len
@@ -85,16 +78,16 @@ __strncpy_user:
85 bbci.l a3, 1, .Lsrcaligned # if src is now word-aligned 78 bbci.l a3, 1, .Lsrcaligned # if src is now word-aligned
86 79
87.Lsrc2mod4: # src address is 2 mod 4 80.Lsrc2mod4: # src address is 2 mod 4
88 EX(l8ui, a9, a3, 0, fixup_l) # get byte 0 81EX(11f) l8ui a9, a3, 0 # get byte 0
89 /* 1-cycle interlock */ 82 /* 1-cycle interlock */
90 EX(s8i, a9, a11, 0, fixup_s) # store byte 0 83EX(10f) s8i a9, a11, 0 # store byte 0
91 beqz a9, .Lret # if byte 0 is zero 84 beqz a9, .Lret # if byte 0 is zero
92 addi a11, a11, 1 # advance dst pointer 85 addi a11, a11, 1 # advance dst pointer
93 addi a4, a4, -1 # decrement len 86 addi a4, a4, -1 # decrement len
94 beqz a4, .Lret # if len is zero 87 beqz a4, .Lret # if len is zero
95 EX(l8ui, a9, a3, 1, fixup_l) # get byte 0 88EX(11f) l8ui a9, a3, 1 # get byte 0
96 addi a3, a3, 2 # advance src pointer 89 addi a3, a3, 2 # advance src pointer
97 EX(s8i, a9, a11, 0, fixup_s) # store byte 0 90EX(10f) s8i a9, a11, 0 # store byte 0
98 beqz a9, .Lret # if byte 0 is zero 91 beqz a9, .Lret # if byte 0 is zero
99 addi a11, a11, 1 # advance dst pointer 92 addi a11, a11, 1 # advance dst pointer
100 addi a4, a4, -1 # decrement len 93 addi a4, a4, -1 # decrement len
@@ -117,12 +110,12 @@ __strncpy_user:
117 add a12, a12, a11 # a12 = end of last 4B chunck 110 add a12, a12, a11 # a12 = end of last 4B chunck
118#endif 111#endif
119.Loop1: 112.Loop1:
120 EX(l32i, a9, a3, 0, fixup_l) # get word from src 113EX(11f) l32i a9, a3, 0 # get word from src
121 addi a3, a3, 4 # advance src pointer 114 addi a3, a3, 4 # advance src pointer
122 bnone a9, a5, .Lz0 # if byte 0 is zero 115 bnone a9, a5, .Lz0 # if byte 0 is zero
123 bnone a9, a6, .Lz1 # if byte 1 is zero 116 bnone a9, a6, .Lz1 # if byte 1 is zero
124 bnone a9, a7, .Lz2 # if byte 2 is zero 117 bnone a9, a7, .Lz2 # if byte 2 is zero
125 EX(s32i, a9, a11, 0, fixup_s) # store word to dst 118EX(10f) s32i a9, a11, 0 # store word to dst
126 bnone a9, a8, .Lz3 # if byte 3 is zero 119 bnone a9, a8, .Lz3 # if byte 3 is zero
127 addi a11, a11, 4 # advance dst pointer 120 addi a11, a11, 4 # advance dst pointer
128#if !XCHAL_HAVE_LOOPS 121#if !XCHAL_HAVE_LOOPS
@@ -132,7 +125,7 @@ __strncpy_user:
132.Loop1done: 125.Loop1done:
133 bbci.l a4, 1, .L100 126 bbci.l a4, 1, .L100
134 # copy 2 bytes 127 # copy 2 bytes
135 EX(l16ui, a9, a3, 0, fixup_l) 128EX(11f) l16ui a9, a3, 0
136 addi a3, a3, 2 # advance src pointer 129 addi a3, a3, 2 # advance src pointer
137#ifdef __XTENSA_EB__ 130#ifdef __XTENSA_EB__
138 bnone a9, a7, .Lz0 # if byte 2 is zero 131 bnone a9, a7, .Lz0 # if byte 2 is zero
@@ -141,13 +134,13 @@ __strncpy_user:
141 bnone a9, a5, .Lz0 # if byte 0 is zero 134 bnone a9, a5, .Lz0 # if byte 0 is zero
142 bnone a9, a6, .Lz1 # if byte 1 is zero 135 bnone a9, a6, .Lz1 # if byte 1 is zero
143#endif 136#endif
144 EX(s16i, a9, a11, 0, fixup_s) 137EX(10f) s16i a9, a11, 0
145 addi a11, a11, 2 # advance dst pointer 138 addi a11, a11, 2 # advance dst pointer
146.L100: 139.L100:
147 bbci.l a4, 0, .Lret 140 bbci.l a4, 0, .Lret
148 EX(l8ui, a9, a3, 0, fixup_l) 141EX(11f) l8ui a9, a3, 0
149 /* slot */ 142 /* slot */
150 EX(s8i, a9, a11, 0, fixup_s) 143EX(10f) s8i a9, a11, 0
151 beqz a9, .Lret # if byte is zero 144 beqz a9, .Lret # if byte is zero
152 addi a11, a11, 1-3 # advance dst ptr 1, but also cancel 145 addi a11, a11, 1-3 # advance dst ptr 1, but also cancel
153 # the effect of adding 3 in .Lz3 code 146 # the effect of adding 3 in .Lz3 code
@@ -161,14 +154,14 @@ __strncpy_user:
161#ifdef __XTENSA_EB__ 154#ifdef __XTENSA_EB__
162 movi a9, 0 155 movi a9, 0
163#endif /* __XTENSA_EB__ */ 156#endif /* __XTENSA_EB__ */
164 EX(s8i, a9, a11, 0, fixup_s) 157EX(10f) s8i a9, a11, 0
165 sub a2, a11, a2 # compute strlen 158 sub a2, a11, a2 # compute strlen
166 retw 159 retw
167.Lz1: # byte 1 is zero 160.Lz1: # byte 1 is zero
168#ifdef __XTENSA_EB__ 161#ifdef __XTENSA_EB__
169 extui a9, a9, 16, 16 162 extui a9, a9, 16, 16
170#endif /* __XTENSA_EB__ */ 163#endif /* __XTENSA_EB__ */
171 EX(s16i, a9, a11, 0, fixup_s) 164EX(10f) s16i a9, a11, 0
172 addi a11, a11, 1 # advance dst pointer 165 addi a11, a11, 1 # advance dst pointer
173 sub a2, a11, a2 # compute strlen 166 sub a2, a11, a2 # compute strlen
174 retw 167 retw
@@ -176,9 +169,9 @@ __strncpy_user:
176#ifdef __XTENSA_EB__ 169#ifdef __XTENSA_EB__
177 extui a9, a9, 16, 16 170 extui a9, a9, 16, 16
178#endif /* __XTENSA_EB__ */ 171#endif /* __XTENSA_EB__ */
179 EX(s16i, a9, a11, 0, fixup_s) 172EX(10f) s16i a9, a11, 0
180 movi a9, 0 173 movi a9, 0
181 EX(s8i, a9, a11, 2, fixup_s) 174EX(10f) s8i a9, a11, 2
182 addi a11, a11, 2 # advance dst pointer 175 addi a11, a11, 2 # advance dst pointer
183 sub a2, a11, a2 # compute strlen 176 sub a2, a11, a2 # compute strlen
184 retw 177 retw
@@ -196,9 +189,9 @@ __strncpy_user:
196 add a12, a11, a4 # a12 = ending address 189 add a12, a11, a4 # a12 = ending address
197#endif /* XCHAL_HAVE_LOOPS */ 190#endif /* XCHAL_HAVE_LOOPS */
198.Lnextbyte: 191.Lnextbyte:
199 EX(l8ui, a9, a3, 0, fixup_l) 192EX(11f) l8ui a9, a3, 0
200 addi a3, a3, 1 193 addi a3, a3, 1
201 EX(s8i, a9, a11, 0, fixup_s) 194EX(10f) s8i a9, a11, 0
202 beqz a9, .Lunalignedend 195 beqz a9, .Lunalignedend
203 addi a11, a11, 1 196 addi a11, a11, 1
204#if !XCHAL_HAVE_LOOPS 197#if !XCHAL_HAVE_LOOPS
@@ -218,8 +211,7 @@ __strncpy_user:
218 * implementation in memset(). Thus, we differentiate between 211 * implementation in memset(). Thus, we differentiate between
219 * load/store fixups. */ 212 * load/store fixups. */
220 213
221fixup_s: 21410:
222fixup_l: 21511:
223 movi a2, -EFAULT 216 movi a2, -EFAULT
224 retw 217 retw
225
diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S
index 4c03b1e581e9..9404ac46ce4c 100644
--- a/arch/xtensa/lib/strnlen_user.S
+++ b/arch/xtensa/lib/strnlen_user.S
@@ -12,14 +12,7 @@
12 */ 12 */
13 13
14#include <variant/core.h> 14#include <variant/core.h>
15 15#include <asm/asmmacro.h>
16/* Load or store instructions that may cause exceptions use the EX macro. */
17
18#define EX(insn,reg1,reg2,offset,handler) \
199: insn reg1, reg2, offset; \
20 .section __ex_table, "a"; \
21 .word 9b, handler; \
22 .previous
23 16
24/* 17/*
25 * size_t __strnlen_user(const char *s, size_t len) 18 * size_t __strnlen_user(const char *s, size_t len)
@@ -77,7 +70,7 @@ __strnlen_user:
77 add a10, a10, a4 # a10 = end of last 4B chunk 70 add a10, a10, a4 # a10 = end of last 4B chunk
78#endif /* XCHAL_HAVE_LOOPS */ 71#endif /* XCHAL_HAVE_LOOPS */
79.Loop: 72.Loop:
80 EX(l32i, a9, a4, 4, lenfixup) # get next word of string 73EX(10f) l32i a9, a4, 4 # get next word of string
81 addi a4, a4, 4 # advance string pointer 74 addi a4, a4, 4 # advance string pointer
82 bnone a9, a5, .Lz0 # if byte 0 is zero 75 bnone a9, a5, .Lz0 # if byte 0 is zero
83 bnone a9, a6, .Lz1 # if byte 1 is zero 76 bnone a9, a6, .Lz1 # if byte 1 is zero
@@ -88,7 +81,7 @@ __strnlen_user:
88#endif 81#endif
89 82
90.Ldone: 83.Ldone:
91 EX(l32i, a9, a4, 4, lenfixup) # load 4 bytes for remaining checks 84EX(10f) l32i a9, a4, 4 # load 4 bytes for remaining checks
92 85
93 bbci.l a3, 1, .L100 86 bbci.l a3, 1, .L100
94 # check two more bytes (bytes 0, 1 of word) 87 # check two more bytes (bytes 0, 1 of word)
@@ -125,14 +118,14 @@ __strnlen_user:
125 retw 118 retw
126 119
127.L1mod2: # address is odd 120.L1mod2: # address is odd
128 EX(l8ui, a9, a4, 4, lenfixup) # get byte 0 121EX(10f) l8ui a9, a4, 4 # get byte 0
129 addi a4, a4, 1 # advance string pointer 122 addi a4, a4, 1 # advance string pointer
130 beqz a9, .Lz3 # if byte 0 is zero 123 beqz a9, .Lz3 # if byte 0 is zero
131 bbci.l a4, 1, .Laligned # if string pointer is now word-aligned 124 bbci.l a4, 1, .Laligned # if string pointer is now word-aligned
132 125
133.L2mod4: # address is 2 mod 4 126.L2mod4: # address is 2 mod 4
134 addi a4, a4, 2 # advance ptr for aligned access 127 addi a4, a4, 2 # advance ptr for aligned access
135 EX(l32i, a9, a4, 0, lenfixup) # get word with first two bytes of string 128EX(10f) l32i a9, a4, 0 # get word with first two bytes of string
136 bnone a9, a7, .Lz2 # if byte 2 (of word, not string) is zero 129 bnone a9, a7, .Lz2 # if byte 2 (of word, not string) is zero
137 bany a9, a8, .Laligned # if byte 3 (of word, not string) is nonzero 130 bany a9, a8, .Laligned # if byte 3 (of word, not string) is nonzero
138 # byte 3 is zero 131 # byte 3 is zero
@@ -142,6 +135,6 @@ __strnlen_user:
142 135
143 .section .fixup, "ax" 136 .section .fixup, "ax"
144 .align 4 137 .align 4
145lenfixup: 13810:
146 movi a2, 0 139 movi a2, 0
147 retw 140 retw
diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S
index d9cd766bde3e..4172b73b0364 100644
--- a/arch/xtensa/lib/usercopy.S
+++ b/arch/xtensa/lib/usercopy.S
@@ -54,6 +54,7 @@
54 */ 54 */
55 55
56#include <variant/core.h> 56#include <variant/core.h>
57#include <asm/asmmacro.h>
57 58
58#ifdef __XTENSA_EB__ 59#ifdef __XTENSA_EB__
59#define ALIGN(R, W0, W1) src R, W0, W1 60#define ALIGN(R, W0, W1) src R, W0, W1
@@ -63,15 +64,6 @@
63#define SSA8(R) ssa8l R 64#define SSA8(R) ssa8l R
64#endif 65#endif
65 66
66/* Load or store instructions that may cause exceptions use the EX macro. */
67
68#define EX(insn,reg1,reg2,offset,handler) \
699: insn reg1, reg2, offset; \
70 .section __ex_table, "a"; \
71 .word 9b, handler; \
72 .previous
73
74
75 .text 67 .text
76 .align 4 68 .align 4
77 .global __xtensa_copy_user 69 .global __xtensa_copy_user
@@ -102,9 +94,9 @@ __xtensa_copy_user:
102 bltui a4, 7, .Lbytecopy # do short copies byte by byte 94 bltui a4, 7, .Lbytecopy # do short copies byte by byte
103 95
104 # copy 1 byte 96 # copy 1 byte
105 EX(l8ui, a6, a3, 0, fixup) 97EX(10f) l8ui a6, a3, 0
106 addi a3, a3, 1 98 addi a3, a3, 1
107 EX(s8i, a6, a5, 0, fixup) 99EX(10f) s8i a6, a5, 0
108 addi a5, a5, 1 100 addi a5, a5, 1
109 addi a4, a4, -1 101 addi a4, a4, -1
110 bbci.l a5, 1, .Ldstaligned # if dst is now aligned, then 102 bbci.l a5, 1, .Ldstaligned # if dst is now aligned, then
@@ -112,11 +104,11 @@ __xtensa_copy_user:
112.Ldst2mod4: # dst 16-bit aligned 104.Ldst2mod4: # dst 16-bit aligned
113 # copy 2 bytes 105 # copy 2 bytes
114 bltui a4, 6, .Lbytecopy # do short copies byte by byte 106 bltui a4, 6, .Lbytecopy # do short copies byte by byte
115 EX(l8ui, a6, a3, 0, fixup) 107EX(10f) l8ui a6, a3, 0
116 EX(l8ui, a7, a3, 1, fixup) 108EX(10f) l8ui a7, a3, 1
117 addi a3, a3, 2 109 addi a3, a3, 2
118 EX(s8i, a6, a5, 0, fixup) 110EX(10f) s8i a6, a5, 0
119 EX(s8i, a7, a5, 1, fixup) 111EX(10f) s8i a7, a5, 1
120 addi a5, a5, 2 112 addi a5, a5, 2
121 addi a4, a4, -2 113 addi a4, a4, -2
122 j .Ldstaligned # dst is now aligned, return to main algorithm 114 j .Ldstaligned # dst is now aligned, return to main algorithm
@@ -135,9 +127,9 @@ __xtensa_copy_user:
135 add a7, a3, a4 # a7 = end address for source 127 add a7, a3, a4 # a7 = end address for source
136#endif /* !XCHAL_HAVE_LOOPS */ 128#endif /* !XCHAL_HAVE_LOOPS */
137.Lnextbyte: 129.Lnextbyte:
138 EX(l8ui, a6, a3, 0, fixup) 130EX(10f) l8ui a6, a3, 0
139 addi a3, a3, 1 131 addi a3, a3, 1
140 EX(s8i, a6, a5, 0, fixup) 132EX(10f) s8i a6, a5, 0
141 addi a5, a5, 1 133 addi a5, a5, 1
142#if !XCHAL_HAVE_LOOPS 134#if !XCHAL_HAVE_LOOPS
143 blt a3, a7, .Lnextbyte 135 blt a3, a7, .Lnextbyte
@@ -161,15 +153,15 @@ __xtensa_copy_user:
161 add a8, a8, a3 # a8 = end of last 16B source chunk 153 add a8, a8, a3 # a8 = end of last 16B source chunk
162#endif /* !XCHAL_HAVE_LOOPS */ 154#endif /* !XCHAL_HAVE_LOOPS */
163.Loop1: 155.Loop1:
164 EX(l32i, a6, a3, 0, fixup) 156EX(10f) l32i a6, a3, 0
165 EX(l32i, a7, a3, 4, fixup) 157EX(10f) l32i a7, a3, 4
166 EX(s32i, a6, a5, 0, fixup) 158EX(10f) s32i a6, a5, 0
167 EX(l32i, a6, a3, 8, fixup) 159EX(10f) l32i a6, a3, 8
168 EX(s32i, a7, a5, 4, fixup) 160EX(10f) s32i a7, a5, 4
169 EX(l32i, a7, a3, 12, fixup) 161EX(10f) l32i a7, a3, 12
170 EX(s32i, a6, a5, 8, fixup) 162EX(10f) s32i a6, a5, 8
171 addi a3, a3, 16 163 addi a3, a3, 16
172 EX(s32i, a7, a5, 12, fixup) 164EX(10f) s32i a7, a5, 12
173 addi a5, a5, 16 165 addi a5, a5, 16
174#if !XCHAL_HAVE_LOOPS 166#if !XCHAL_HAVE_LOOPS
175 blt a3, a8, .Loop1 167 blt a3, a8, .Loop1
@@ -177,31 +169,31 @@ __xtensa_copy_user:
177.Loop1done: 169.Loop1done:
178 bbci.l a4, 3, .L2 170 bbci.l a4, 3, .L2
179 # copy 8 bytes 171 # copy 8 bytes
180 EX(l32i, a6, a3, 0, fixup) 172EX(10f) l32i a6, a3, 0
181 EX(l32i, a7, a3, 4, fixup) 173EX(10f) l32i a7, a3, 4
182 addi a3, a3, 8 174 addi a3, a3, 8
183 EX(s32i, a6, a5, 0, fixup) 175EX(10f) s32i a6, a5, 0
184 EX(s32i, a7, a5, 4, fixup) 176EX(10f) s32i a7, a5, 4
185 addi a5, a5, 8 177 addi a5, a5, 8
186.L2: 178.L2:
187 bbci.l a4, 2, .L3 179 bbci.l a4, 2, .L3
188 # copy 4 bytes 180 # copy 4 bytes
189 EX(l32i, a6, a3, 0, fixup) 181EX(10f) l32i a6, a3, 0
190 addi a3, a3, 4 182 addi a3, a3, 4
191 EX(s32i, a6, a5, 0, fixup) 183EX(10f) s32i a6, a5, 0
192 addi a5, a5, 4 184 addi a5, a5, 4
193.L3: 185.L3:
194 bbci.l a4, 1, .L4 186 bbci.l a4, 1, .L4
195 # copy 2 bytes 187 # copy 2 bytes
196 EX(l16ui, a6, a3, 0, fixup) 188EX(10f) l16ui a6, a3, 0
197 addi a3, a3, 2 189 addi a3, a3, 2
198 EX(s16i, a6, a5, 0, fixup) 190EX(10f) s16i a6, a5, 0
199 addi a5, a5, 2 191 addi a5, a5, 2
200.L4: 192.L4:
201 bbci.l a4, 0, .L5 193 bbci.l a4, 0, .L5
202 # copy 1 byte 194 # copy 1 byte
203 EX(l8ui, a6, a3, 0, fixup) 195EX(10f) l8ui a6, a3, 0
204 EX(s8i, a6, a5, 0, fixup) 196EX(10f) s8i a6, a5, 0
205.L5: 197.L5:
206 movi a2, 0 # return success for len bytes copied 198 movi a2, 0 # return success for len bytes copied
207 retw 199 retw
@@ -217,7 +209,7 @@ __xtensa_copy_user:
217 # copy 16 bytes per iteration for word-aligned dst and unaligned src 209 # copy 16 bytes per iteration for word-aligned dst and unaligned src
218 and a10, a3, a8 # save unalignment offset for below 210 and a10, a3, a8 # save unalignment offset for below
219 sub a3, a3, a10 # align a3 (to avoid sim warnings only; not needed for hardware) 211 sub a3, a3, a10 # align a3 (to avoid sim warnings only; not needed for hardware)
220 EX(l32i, a6, a3, 0, fixup) # load first word 212EX(10f) l32i a6, a3, 0 # load first word
221#if XCHAL_HAVE_LOOPS 213#if XCHAL_HAVE_LOOPS
222 loopnez a7, .Loop2done 214 loopnez a7, .Loop2done
223#else /* !XCHAL_HAVE_LOOPS */ 215#else /* !XCHAL_HAVE_LOOPS */
@@ -226,19 +218,19 @@ __xtensa_copy_user:
226 add a12, a12, a3 # a12 = end of last 16B source chunk 218 add a12, a12, a3 # a12 = end of last 16B source chunk
227#endif /* !XCHAL_HAVE_LOOPS */ 219#endif /* !XCHAL_HAVE_LOOPS */
228.Loop2: 220.Loop2:
229 EX(l32i, a7, a3, 4, fixup) 221EX(10f) l32i a7, a3, 4
230 EX(l32i, a8, a3, 8, fixup) 222EX(10f) l32i a8, a3, 8
231 ALIGN( a6, a6, a7) 223 ALIGN( a6, a6, a7)
232 EX(s32i, a6, a5, 0, fixup) 224EX(10f) s32i a6, a5, 0
233 EX(l32i, a9, a3, 12, fixup) 225EX(10f) l32i a9, a3, 12
234 ALIGN( a7, a7, a8) 226 ALIGN( a7, a7, a8)
235 EX(s32i, a7, a5, 4, fixup) 227EX(10f) s32i a7, a5, 4
236 EX(l32i, a6, a3, 16, fixup) 228EX(10f) l32i a6, a3, 16
237 ALIGN( a8, a8, a9) 229 ALIGN( a8, a8, a9)
238 EX(s32i, a8, a5, 8, fixup) 230EX(10f) s32i a8, a5, 8
239 addi a3, a3, 16 231 addi a3, a3, 16
240 ALIGN( a9, a9, a6) 232 ALIGN( a9, a9, a6)
241 EX(s32i, a9, a5, 12, fixup) 233EX(10f) s32i a9, a5, 12
242 addi a5, a5, 16 234 addi a5, a5, 16
243#if !XCHAL_HAVE_LOOPS 235#if !XCHAL_HAVE_LOOPS
244 blt a3, a12, .Loop2 236 blt a3, a12, .Loop2
@@ -246,39 +238,39 @@ __xtensa_copy_user:
246.Loop2done: 238.Loop2done:
247 bbci.l a4, 3, .L12 239 bbci.l a4, 3, .L12
248 # copy 8 bytes 240 # copy 8 bytes
249 EX(l32i, a7, a3, 4, fixup) 241EX(10f) l32i a7, a3, 4
250 EX(l32i, a8, a3, 8, fixup) 242EX(10f) l32i a8, a3, 8
251 ALIGN( a6, a6, a7) 243 ALIGN( a6, a6, a7)
252 EX(s32i, a6, a5, 0, fixup) 244EX(10f) s32i a6, a5, 0
253 addi a3, a3, 8 245 addi a3, a3, 8
254 ALIGN( a7, a7, a8) 246 ALIGN( a7, a7, a8)
255 EX(s32i, a7, a5, 4, fixup) 247EX(10f) s32i a7, a5, 4
256 addi a5, a5, 8 248 addi a5, a5, 8
257 mov a6, a8 249 mov a6, a8
258.L12: 250.L12:
259 bbci.l a4, 2, .L13 251 bbci.l a4, 2, .L13
260 # copy 4 bytes 252 # copy 4 bytes
261 EX(l32i, a7, a3, 4, fixup) 253EX(10f) l32i a7, a3, 4
262 addi a3, a3, 4 254 addi a3, a3, 4
263 ALIGN( a6, a6, a7) 255 ALIGN( a6, a6, a7)
264 EX(s32i, a6, a5, 0, fixup) 256EX(10f) s32i a6, a5, 0
265 addi a5, a5, 4 257 addi a5, a5, 4
266 mov a6, a7 258 mov a6, a7
267.L13: 259.L13:
268 add a3, a3, a10 # readjust a3 with correct misalignment 260 add a3, a3, a10 # readjust a3 with correct misalignment
269 bbci.l a4, 1, .L14 261 bbci.l a4, 1, .L14
270 # copy 2 bytes 262 # copy 2 bytes
271 EX(l8ui, a6, a3, 0, fixup) 263EX(10f) l8ui a6, a3, 0
272 EX(l8ui, a7, a3, 1, fixup) 264EX(10f) l8ui a7, a3, 1
273 addi a3, a3, 2 265 addi a3, a3, 2
274 EX(s8i, a6, a5, 0, fixup) 266EX(10f) s8i a6, a5, 0
275 EX(s8i, a7, a5, 1, fixup) 267EX(10f) s8i a7, a5, 1
276 addi a5, a5, 2 268 addi a5, a5, 2
277.L14: 269.L14:
278 bbci.l a4, 0, .L15 270 bbci.l a4, 0, .L15
279 # copy 1 byte 271 # copy 1 byte
280 EX(l8ui, a6, a3, 0, fixup) 272EX(10f) l8ui a6, a3, 0
281 EX(s8i, a6, a5, 0, fixup) 273EX(10f) s8i a6, a5, 0
282.L15: 274.L15:
283 movi a2, 0 # return success for len bytes copied 275 movi a2, 0 # return success for len bytes copied
284 retw 276 retw
@@ -294,7 +286,7 @@ __xtensa_copy_user:
294 */ 286 */
295 287
296 288
297fixup: 28910:
298 sub a2, a5, a2 /* a2 <-- bytes copied */ 290 sub a2, a5, a2 /* a2 <-- bytes copied */
299 sub a2, a11, a2 /* a2 <-- bytes not copied */ 291 sub a2, a11, a2 /* a2 <-- bytes not copied */
300 retw 292 retw