~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/rseq/rseq-arm-bits.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
  2 /*
  3  * rseq-arm-bits.h
  4  *
  5  * (C) Copyright 2016-2022 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  6  */
  7 
  8 #include "rseq-bits-template.h"
  9 
 10 #if defined(RSEQ_TEMPLATE_MO_RELAXED) && \
 11         (defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID))
 12 
 13 static inline __attribute__((always_inline))
 14 int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_storev)(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
 15 {
 16         RSEQ_INJECT_C(9)
 17 
 18         __asm__ __volatile__ goto (
 19                 RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
 20                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
 21 #ifdef RSEQ_COMPARE_TWICE
 22                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
 23                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
 24 #endif
 25                 /* Start rseq by storing table entry pointer into rseq_cs. */
 26                 RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs)
 27                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
 28                 RSEQ_INJECT_ASM(3)
 29                 "ldr r0, %[v]\n\t"
 30                 "cmp %[expect], r0\n\t"
 31                 "bne %l[cmpfail]\n\t"
 32                 RSEQ_INJECT_ASM(4)
 33 #ifdef RSEQ_COMPARE_TWICE
 34                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
 35                 "ldr r0, %[v]\n\t"
 36                 "cmp %[expect], r0\n\t"
 37                 "bne %l[error2]\n\t"
 38 #endif
 39                 /* final store */
 40                 "str %[newv], %[v]\n\t"
 41                 "2:\n\t"
 42                 RSEQ_INJECT_ASM(5)
 43                 "b 5f\n\t"
 44                 RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
 45                 "5:\n\t"
 46                 : /* gcc asm goto does not allow outputs */
 47                 : [cpu_id]              "r" (cpu),
 48                   [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
 49                   [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
 50                   [v]                   "m" (*v),
 51                   [expect]              "r" (expect),
 52                   [newv]                "r" (newv)
 53                   RSEQ_INJECT_INPUT
 54                 : "r0", "memory", "cc"
 55                   RSEQ_INJECT_CLOBBER
 56                 : abort, cmpfail
 57 #ifdef RSEQ_COMPARE_TWICE
 58                   , error1, error2
 59 #endif
 60         );
 61         rseq_after_asm_goto();
 62         return 0;
 63 abort:
 64         rseq_after_asm_goto();
 65         RSEQ_INJECT_FAILED
 66         return -1;
 67 cmpfail:
 68         rseq_after_asm_goto();
 69         return 1;
 70 #ifdef RSEQ_COMPARE_TWICE
 71 error1:
 72         rseq_after_asm_goto();
 73         rseq_bug("cpu_id comparison failed");
 74 error2:
 75         rseq_after_asm_goto();
 76         rseq_bug("expected value comparison failed");
 77 #endif
 78 }
 79 
 80 static inline __attribute__((always_inline))
 81 int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpnev_storeoffp_load)(intptr_t *v, intptr_t expectnot,
 82                                long voffp, intptr_t *load, int cpu)
 83 {
 84         RSEQ_INJECT_C(9)
 85 
 86         __asm__ __volatile__ goto (
 87                 RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
 88                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
 89 #ifdef RSEQ_COMPARE_TWICE
 90                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
 91                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
 92 #endif
 93                 /* Start rseq by storing table entry pointer into rseq_cs. */
 94                 RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs)
 95                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
 96                 RSEQ_INJECT_ASM(3)
 97                 "ldr r0, %[v]\n\t"
 98                 "cmp %[expectnot], r0\n\t"
 99                 "beq %l[cmpfail]\n\t"
100                 RSEQ_INJECT_ASM(4)
101 #ifdef RSEQ_COMPARE_TWICE
102                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
103                 "ldr r0, %[v]\n\t"
104                 "cmp %[expectnot], r0\n\t"
105                 "beq %l[error2]\n\t"
106 #endif
107                 "str r0, %[load]\n\t"
108                 "add r0, %[voffp]\n\t"
109                 "ldr r0, [r0]\n\t"
110                 /* final store */
111                 "str r0, %[v]\n\t"
112                 "2:\n\t"
113                 RSEQ_INJECT_ASM(5)
114                 "b 5f\n\t"
115                 RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
116                 "5:\n\t"
117                 : /* gcc asm goto does not allow outputs */
118                 : [cpu_id]              "r" (cpu),
119                   [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
120                   [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
121                   /* final store input */
122                   [v]                   "m" (*v),
123                   [expectnot]           "r" (expectnot),
124                   [voffp]               "Ir" (voffp),
125                   [load]                "m" (*load)
126                   RSEQ_INJECT_INPUT
127                 : "r0", "memory", "cc"
128                   RSEQ_INJECT_CLOBBER
129                 : abort, cmpfail
130 #ifdef RSEQ_COMPARE_TWICE
131                   , error1, error2
132 #endif
133         );
134         rseq_after_asm_goto();
135         return 0;
136 abort:
137         rseq_after_asm_goto();
138         RSEQ_INJECT_FAILED
139         return -1;
140 cmpfail:
141         rseq_after_asm_goto();
142         return 1;
143 #ifdef RSEQ_COMPARE_TWICE
144 error1:
145         rseq_after_asm_goto();
146         rseq_bug("cpu_id comparison failed");
147 error2:
148         rseq_after_asm_goto();
149         rseq_bug("expected value comparison failed");
150 #endif
151 }
152 
153 static inline __attribute__((always_inline))
154 int RSEQ_TEMPLATE_IDENTIFIER(rseq_addv)(intptr_t *v, intptr_t count, int cpu)
155 {
156         RSEQ_INJECT_C(9)
157 
158         __asm__ __volatile__ goto (
159                 RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
160 #ifdef RSEQ_COMPARE_TWICE
161                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
162 #endif
163                 /* Start rseq by storing table entry pointer into rseq_cs. */
164                 RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs)
165                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
166                 RSEQ_INJECT_ASM(3)
167 #ifdef RSEQ_COMPARE_TWICE
168                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
169 #endif
170                 "ldr r0, %[v]\n\t"
171                 "add r0, %[count]\n\t"
172                 /* final store */
173                 "str r0, %[v]\n\t"
174                 "2:\n\t"
175                 RSEQ_INJECT_ASM(4)
176                 "b 5f\n\t"
177                 RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
178                 "5:\n\t"
179                 : /* gcc asm goto does not allow outputs */
180                 : [cpu_id]              "r" (cpu),
181                   [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
182                   [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
183                   [v]                   "m" (*v),
184                   [count]               "Ir" (count)
185                   RSEQ_INJECT_INPUT
186                 : "r0", "memory", "cc"
187                   RSEQ_INJECT_CLOBBER
188                 : abort
189 #ifdef RSEQ_COMPARE_TWICE
190                   , error1
191 #endif
192         );
193         rseq_after_asm_goto();
194         return 0;
195 abort:
196         rseq_after_asm_goto();
197         RSEQ_INJECT_FAILED
198         return -1;
199 #ifdef RSEQ_COMPARE_TWICE
200 error1:
201         rseq_after_asm_goto();
202         rseq_bug("cpu_id comparison failed");
203 #endif
204 }
205 
206 static inline __attribute__((always_inline))
207 int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_cmpeqv_storev)(intptr_t *v, intptr_t expect,
208                               intptr_t *v2, intptr_t expect2,
209                               intptr_t newv, int cpu)
210 {
211         RSEQ_INJECT_C(9)
212 
213         __asm__ __volatile__ goto (
214                 RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
215                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
216 #ifdef RSEQ_COMPARE_TWICE
217                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
218                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
219                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error3])
220 #endif
221                 /* Start rseq by storing table entry pointer into rseq_cs. */
222                 RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs)
223                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
224                 RSEQ_INJECT_ASM(3)
225                 "ldr r0, %[v]\n\t"
226                 "cmp %[expect], r0\n\t"
227                 "bne %l[cmpfail]\n\t"
228                 RSEQ_INJECT_ASM(4)
229                 "ldr r0, %[v2]\n\t"
230                 "cmp %[expect2], r0\n\t"
231                 "bne %l[cmpfail]\n\t"
232                 RSEQ_INJECT_ASM(5)
233 #ifdef RSEQ_COMPARE_TWICE
234                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
235                 "ldr r0, %[v]\n\t"
236                 "cmp %[expect], r0\n\t"
237                 "bne %l[error2]\n\t"
238                 "ldr r0, %[v2]\n\t"
239                 "cmp %[expect2], r0\n\t"
240                 "bne %l[error3]\n\t"
241 #endif
242                 /* final store */
243                 "str %[newv], %[v]\n\t"
244                 "2:\n\t"
245                 RSEQ_INJECT_ASM(6)
246                 "b 5f\n\t"
247                 RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
248                 "5:\n\t"
249                 : /* gcc asm goto does not allow outputs */
250                 : [cpu_id]              "r" (cpu),
251                   [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
252                   [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
253                   /* cmp2 input */
254                   [v2]                  "m" (*v2),
255                   [expect2]             "r" (expect2),
256                   /* final store input */
257                   [v]                   "m" (*v),
258                   [expect]              "r" (expect),
259                   [newv]                "r" (newv)
260                   RSEQ_INJECT_INPUT
261                 : "r0", "memory", "cc"
262                   RSEQ_INJECT_CLOBBER
263                 : abort, cmpfail
264 #ifdef RSEQ_COMPARE_TWICE
265                   , error1, error2, error3
266 #endif
267         );
268         rseq_after_asm_goto();
269         return 0;
270 abort:
271         rseq_after_asm_goto();
272         RSEQ_INJECT_FAILED
273         return -1;
274 cmpfail:
275         rseq_after_asm_goto();
276         return 1;
277 #ifdef RSEQ_COMPARE_TWICE
278 error1:
279         rseq_after_asm_goto();
280         rseq_bug("cpu_id comparison failed");
281 error2:
282         rseq_after_asm_goto();
283         rseq_bug("1st expected value comparison failed");
284 error3:
285         rseq_after_asm_goto();
286         rseq_bug("2nd expected value comparison failed");
287 #endif
288 }
289 
290 #endif /* #if defined(RSEQ_TEMPLATE_MO_RELAXED) &&
291         (defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID)) */
292 
293 #if (defined(RSEQ_TEMPLATE_MO_RELAXED) || defined(RSEQ_TEMPLATE_MO_RELEASE)) && \
294         (defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID))
295 
296 static inline __attribute__((always_inline))
297 int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_trystorev_storev)(intptr_t *v, intptr_t expect,
298                                  intptr_t *v2, intptr_t newv2,
299                                  intptr_t newv, int cpu)
300 {
301         RSEQ_INJECT_C(9)
302 
303         __asm__ __volatile__ goto (
304                 RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
305                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
306 #ifdef RSEQ_COMPARE_TWICE
307                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
308                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
309 #endif
310                 /* Start rseq by storing table entry pointer into rseq_cs. */
311                 RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs)
312                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
313                 RSEQ_INJECT_ASM(3)
314                 "ldr r0, %[v]\n\t"
315                 "cmp %[expect], r0\n\t"
316                 "bne %l[cmpfail]\n\t"
317                 RSEQ_INJECT_ASM(4)
318 #ifdef RSEQ_COMPARE_TWICE
319                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
320                 "ldr r0, %[v]\n\t"
321                 "cmp %[expect], r0\n\t"
322                 "bne %l[error2]\n\t"
323 #endif
324                 /* try store */
325                 "str %[newv2], %[v2]\n\t"
326                 RSEQ_INJECT_ASM(5)
327 #ifdef RSEQ_TEMPLATE_MO_RELEASE
328                 "dmb\n\t"       /* full mb provides store-release */
329 #endif
330                 /* final store */
331                 "str %[newv], %[v]\n\t"
332                 "2:\n\t"
333                 RSEQ_INJECT_ASM(6)
334                 "b 5f\n\t"
335                 RSEQ_ASM_DEFINE_ABORT(3, 4, "", abort, 1b, 2b, 4f)
336                 "5:\n\t"
337                 : /* gcc asm goto does not allow outputs */
338                 : [cpu_id]              "r" (cpu),
339                   [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
340                   [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
341                   /* try store input */
342                   [v2]                  "m" (*v2),
343                   [newv2]               "r" (newv2),
344                   /* final store input */
345                   [v]                   "m" (*v),
346                   [expect]              "r" (expect),
347                   [newv]                "r" (newv)
348                   RSEQ_INJECT_INPUT
349                 : "r0", "memory", "cc"
350                   RSEQ_INJECT_CLOBBER
351                 : abort, cmpfail
352 #ifdef RSEQ_COMPARE_TWICE
353                   , error1, error2
354 #endif
355         );
356         rseq_after_asm_goto();
357         return 0;
358 abort:
359         rseq_after_asm_goto();
360         RSEQ_INJECT_FAILED
361         return -1;
362 cmpfail:
363         rseq_after_asm_goto();
364         return 1;
365 #ifdef RSEQ_COMPARE_TWICE
366 error1:
367         rseq_after_asm_goto();
368         rseq_bug("cpu_id comparison failed");
369 error2:
370         rseq_after_asm_goto();
371         rseq_bug("expected value comparison failed");
372 #endif
373 }
374 
375 
376 static inline __attribute__((always_inline))
377 int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_trymemcpy_storev)(intptr_t *v, intptr_t expect,
378                                  void *dst, void *src, size_t len,
379                                  intptr_t newv, int cpu)
380 {
381         uint32_t rseq_scratch[3];
382 
383         RSEQ_INJECT_C(9)
384 
385         __asm__ __volatile__ goto (
386                 RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
387                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
388 #ifdef RSEQ_COMPARE_TWICE
389                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
390                 RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
391 #endif
392                 "str %[src], %[rseq_scratch0]\n\t"
393                 "str %[dst], %[rseq_scratch1]\n\t"
394                 "str %[len], %[rseq_scratch2]\n\t"
395                 /* Start rseq by storing table entry pointer into rseq_cs. */
396                 RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs)
397                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
398                 RSEQ_INJECT_ASM(3)
399                 "ldr r0, %[v]\n\t"
400                 "cmp %[expect], r0\n\t"
401                 "bne 5f\n\t"
402                 RSEQ_INJECT_ASM(4)
403 #ifdef RSEQ_COMPARE_TWICE
404                 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 6f)
405                 "ldr r0, %[v]\n\t"
406                 "cmp %[expect], r0\n\t"
407                 "bne 7f\n\t"
408 #endif
409                 /* try memcpy */
410                 "cmp %[len], #0\n\t" \
411                 "beq 333f\n\t" \
412                 "222:\n\t" \
413                 "ldrb %%r0, [%[src]]\n\t" \
414                 "strb %%r0, [%[dst]]\n\t" \
415                 "adds %[src], #1\n\t" \
416                 "adds %[dst], #1\n\t" \
417                 "subs %[len], #1\n\t" \
418                 "bne 222b\n\t" \
419                 "333:\n\t" \
420                 RSEQ_INJECT_ASM(5)
421 #ifdef RSEQ_TEMPLATE_MO_RELEASE
422                 "dmb\n\t"       /* full mb provides store-release */
423 #endif
424                 /* final store */
425                 "str %[newv], %[v]\n\t"
426                 "2:\n\t"
427                 RSEQ_INJECT_ASM(6)
428                 /* teardown */
429                 "ldr %[len], %[rseq_scratch2]\n\t"
430                 "ldr %[dst], %[rseq_scratch1]\n\t"
431                 "ldr %[src], %[rseq_scratch0]\n\t"
432                 "b 8f\n\t"
433                 RSEQ_ASM_DEFINE_ABORT(3, 4,
434                                       /* teardown */
435                                       "ldr %[len], %[rseq_scratch2]\n\t"
436                                       "ldr %[dst], %[rseq_scratch1]\n\t"
437                                       "ldr %[src], %[rseq_scratch0]\n\t",
438                                       abort, 1b, 2b, 4f)
439                 RSEQ_ASM_DEFINE_CMPFAIL(5,
440                                         /* teardown */
441                                         "ldr %[len], %[rseq_scratch2]\n\t"
442                                         "ldr %[dst], %[rseq_scratch1]\n\t"
443                                         "ldr %[src], %[rseq_scratch0]\n\t",
444                                         cmpfail)
445 #ifdef RSEQ_COMPARE_TWICE
446                 RSEQ_ASM_DEFINE_CMPFAIL(6,
447                                         /* teardown */
448                                         "ldr %[len], %[rseq_scratch2]\n\t"
449                                         "ldr %[dst], %[rseq_scratch1]\n\t"
450                                         "ldr %[src], %[rseq_scratch0]\n\t",
451                                         error1)
452                 RSEQ_ASM_DEFINE_CMPFAIL(7,
453                                         /* teardown */
454                                         "ldr %[len], %[rseq_scratch2]\n\t"
455                                         "ldr %[dst], %[rseq_scratch1]\n\t"
456                                         "ldr %[src], %[rseq_scratch0]\n\t",
457                                         error2)
458 #endif
459                 "8:\n\t"
460                 : /* gcc asm goto does not allow outputs */
461                 : [cpu_id]              "r" (cpu),
462                   [current_cpu_id]      "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
463                   [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
464                   /* final store input */
465                   [v]                   "m" (*v),
466                   [expect]              "r" (expect),
467                   [newv]                "r" (newv),
468                   /* try memcpy input */
469                   [dst]                 "r" (dst),
470                   [src]                 "r" (src),
471                   [len]                 "r" (len),
472                   [rseq_scratch0]       "m" (rseq_scratch[0]),
473                   [rseq_scratch1]       "m" (rseq_scratch[1]),
474                   [rseq_scratch2]       "m" (rseq_scratch[2])
475                   RSEQ_INJECT_INPUT
476                 : "r0", "memory", "cc"
477                   RSEQ_INJECT_CLOBBER
478                 : abort, cmpfail
479 #ifdef RSEQ_COMPARE_TWICE
480                   , error1, error2
481 #endif
482         );
483         rseq_after_asm_goto();
484         return 0;
485 abort:
486         rseq_after_asm_goto();
487         RSEQ_INJECT_FAILED
488         return -1;
489 cmpfail:
490         rseq_after_asm_goto();
491         return 1;
492 #ifdef RSEQ_COMPARE_TWICE
493 error1:
494         rseq_after_asm_goto();
495         rseq_bug("cpu_id comparison failed");
496 error2:
497         rseq_after_asm_goto();
498         rseq_bug("expected value comparison failed");
499 #endif
500 }
501 
502 #endif /* #if (defined(RSEQ_TEMPLATE_MO_RELAXED) || defined(RSEQ_TEMPLATE_MO_RELEASE)) &&
503         (defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID)) */
504 
505 #include "rseq-bits-reset.h"
506 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php