hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/tools/testing/selftests/rseq/rseq-arm64.h
....@@ -6,7 +6,20 @@
66 * (C) Copyright 2018 - Will Deacon <will.deacon@arm.com>
77 */
88
9
-#define RSEQ_SIG 0xd428bc00 /* BRK #0x45E0 */
9
+/*
10
+ * aarch64 -mbig-endian generates mixed endianness code vs data:
11
+ * little-endian code and big-endian data. Ensure the RSEQ_SIG signature
12
+ * matches code endianness.
13
+ */
14
+#define RSEQ_SIG_CODE 0xd428bc00 /* BRK #0x45E0. */
15
+
16
+#ifdef __AARCH64EB__
17
+#define RSEQ_SIG_DATA 0x00bc28d4 /* BRK #0x45E0. */
18
+#else
19
+#define RSEQ_SIG_DATA RSEQ_SIG_CODE
20
+#endif
21
+
22
+#define RSEQ_SIG RSEQ_SIG_DATA
1023
1124 #define rseq_smp_mb() __asm__ __volatile__ ("dmb ish" ::: "memory")
1225 #define rseq_smp_rmb() __asm__ __volatile__ ("dmb ishld" ::: "memory")
....@@ -82,18 +95,34 @@
8295
8396 #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip, \
8497 post_commit_offset, abort_ip) \
85
- " .pushsection __rseq_table, \"aw\"\n" \
98
+ " .pushsection __rseq_cs, \"aw\"\n" \
8699 " .balign 32\n" \
87100 __rseq_str(label) ":\n" \
88101 " .long " __rseq_str(version) ", " __rseq_str(flags) "\n" \
89102 " .quad " __rseq_str(start_ip) ", " \
90103 __rseq_str(post_commit_offset) ", " \
91104 __rseq_str(abort_ip) "\n" \
105
+ " .popsection\n\t" \
106
+ " .pushsection __rseq_cs_ptr_array, \"aw\"\n" \
107
+ " .quad " __rseq_str(label) "b\n" \
92108 " .popsection\n"
93109
94110 #define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \
95111 __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \
96112 (post_commit_ip - start_ip), abort_ip)
113
+
114
+/*
115
+ * Exit points of a rseq critical section consist of all instructions outside
116
+ * of the critical section where a critical section can either branch to or
117
+ * reach through the normal course of its execution. The abort IP and the
118
+ * post-commit IP are already part of the __rseq_cs section and should not be
119
+ * explicitly defined as additional exit points. Knowing all exit points is
120
+ * useful to assist debuggers stepping over the critical section.
121
+ */
122
+#define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip) \
123
+ " .pushsection __rseq_exit_point_array, \"aw\"\n" \
124
+ " .quad " __rseq_str(start_ip) ", " __rseq_str(exit_ip) "\n" \
125
+ " .popsection\n"
97126
98127 #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \
99128 RSEQ_INJECT_ASM(1) \
....@@ -105,7 +134,7 @@
105134
106135 #define RSEQ_ASM_DEFINE_ABORT(label, abort_label) \
107136 " b 222f\n" \
108
- " .inst " __rseq_str(RSEQ_SIG) "\n" \
137
+ " .inst " __rseq_str(RSEQ_SIG_CODE) "\n" \
109138 __rseq_str(label) ":\n" \
110139 " b %l[" __rseq_str(abort_label) "]\n" \
111140 "222:\n"
....@@ -182,6 +211,11 @@
182211
183212 __asm__ __volatile__ goto (
184213 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
214
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
215
+#ifdef RSEQ_COMPARE_TWICE
216
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
217
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
218
+#endif
185219 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
186220 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
187221 RSEQ_INJECT_ASM(3)
....@@ -196,8 +230,8 @@
196230 RSEQ_ASM_DEFINE_ABORT(4, abort)
197231 : /* gcc asm goto does not allow outputs */
198232 : [cpu_id] "r" (cpu),
199
- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
200
- [rseq_cs] "m" (__rseq_abi.rseq_cs),
233
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
234
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
201235 [v] "Qo" (*v),
202236 [expect] "r" (expect),
203237 [newv] "r" (newv)
....@@ -208,29 +242,38 @@
208242 , error1, error2
209243 #endif
210244 );
211
-
245
+ rseq_after_asm_goto();
212246 return 0;
213247 abort:
248
+ rseq_after_asm_goto();
214249 RSEQ_INJECT_FAILED
215250 return -1;
216251 cmpfail:
252
+ rseq_after_asm_goto();
217253 return 1;
218254 #ifdef RSEQ_COMPARE_TWICE
219255 error1:
256
+ rseq_after_asm_goto();
220257 rseq_bug("cpu_id comparison failed");
221258 error2:
259
+ rseq_after_asm_goto();
222260 rseq_bug("expected value comparison failed");
223261 #endif
224262 }
225263
226264 static inline __attribute__((always_inline))
227265 int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
228
- off_t voffp, intptr_t *load, int cpu)
266
+ long voffp, intptr_t *load, int cpu)
229267 {
230268 RSEQ_INJECT_C(9)
231269
232270 __asm__ __volatile__ goto (
233271 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
272
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
273
+#ifdef RSEQ_COMPARE_TWICE
274
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
275
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
276
+#endif
234277 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
235278 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
236279 RSEQ_INJECT_ASM(3)
....@@ -248,8 +291,8 @@
248291 RSEQ_ASM_DEFINE_ABORT(4, abort)
249292 : /* gcc asm goto does not allow outputs */
250293 : [cpu_id] "r" (cpu),
251
- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
252
- [rseq_cs] "m" (__rseq_abi.rseq_cs),
294
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
295
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
253296 [v] "Qo" (*v),
254297 [expectnot] "r" (expectnot),
255298 [load] "Qo" (*load),
....@@ -261,16 +304,21 @@
261304 , error1, error2
262305 #endif
263306 );
307
+ rseq_after_asm_goto();
264308 return 0;
265309 abort:
310
+ rseq_after_asm_goto();
266311 RSEQ_INJECT_FAILED
267312 return -1;
268313 cmpfail:
314
+ rseq_after_asm_goto();
269315 return 1;
270316 #ifdef RSEQ_COMPARE_TWICE
271317 error1:
318
+ rseq_after_asm_goto();
272319 rseq_bug("cpu_id comparison failed");
273320 error2:
321
+ rseq_after_asm_goto();
274322 rseq_bug("expected value comparison failed");
275323 #endif
276324 }
....@@ -282,6 +330,9 @@
282330
283331 __asm__ __volatile__ goto (
284332 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
333
+#ifdef RSEQ_COMPARE_TWICE
334
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
335
+#endif
285336 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
286337 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
287338 RSEQ_INJECT_ASM(3)
....@@ -295,8 +346,8 @@
295346 RSEQ_ASM_DEFINE_ABORT(4, abort)
296347 : /* gcc asm goto does not allow outputs */
297348 : [cpu_id] "r" (cpu),
298
- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
299
- [rseq_cs] "m" (__rseq_abi.rseq_cs),
349
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
350
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
300351 [v] "Qo" (*v),
301352 [count] "r" (count)
302353 RSEQ_INJECT_INPUT
....@@ -306,12 +357,15 @@
306357 , error1
307358 #endif
308359 );
360
+ rseq_after_asm_goto();
309361 return 0;
310362 abort:
363
+ rseq_after_asm_goto();
311364 RSEQ_INJECT_FAILED
312365 return -1;
313366 #ifdef RSEQ_COMPARE_TWICE
314367 error1:
368
+ rseq_after_asm_goto();
315369 rseq_bug("cpu_id comparison failed");
316370 #endif
317371 }
....@@ -325,6 +379,11 @@
325379
326380 __asm__ __volatile__ goto (
327381 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
382
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
383
+#ifdef RSEQ_COMPARE_TWICE
384
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
385
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
386
+#endif
328387 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
329388 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
330389 RSEQ_INJECT_ASM(3)
....@@ -341,8 +400,8 @@
341400 RSEQ_ASM_DEFINE_ABORT(4, abort)
342401 : /* gcc asm goto does not allow outputs */
343402 : [cpu_id] "r" (cpu),
344
- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
345
- [rseq_cs] "m" (__rseq_abi.rseq_cs),
403
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
404
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
346405 [expect] "r" (expect),
347406 [v] "Qo" (*v),
348407 [newv] "r" (newv),
....@@ -355,17 +414,21 @@
355414 , error1, error2
356415 #endif
357416 );
358
-
417
+ rseq_after_asm_goto();
359418 return 0;
360419 abort:
420
+ rseq_after_asm_goto();
361421 RSEQ_INJECT_FAILED
362422 return -1;
363423 cmpfail:
424
+ rseq_after_asm_goto();
364425 return 1;
365426 #ifdef RSEQ_COMPARE_TWICE
366427 error1:
428
+ rseq_after_asm_goto();
367429 rseq_bug("cpu_id comparison failed");
368430 error2:
431
+ rseq_after_asm_goto();
369432 rseq_bug("expected value comparison failed");
370433 #endif
371434 }
....@@ -379,6 +442,11 @@
379442
380443 __asm__ __volatile__ goto (
381444 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
445
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
446
+#ifdef RSEQ_COMPARE_TWICE
447
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
448
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
449
+#endif
382450 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
383451 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
384452 RSEQ_INJECT_ASM(3)
....@@ -395,8 +463,8 @@
395463 RSEQ_ASM_DEFINE_ABORT(4, abort)
396464 : /* gcc asm goto does not allow outputs */
397465 : [cpu_id] "r" (cpu),
398
- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
399
- [rseq_cs] "m" (__rseq_abi.rseq_cs),
466
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
467
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
400468 [expect] "r" (expect),
401469 [v] "Qo" (*v),
402470 [newv] "r" (newv),
....@@ -409,17 +477,21 @@
409477 , error1, error2
410478 #endif
411479 );
412
-
480
+ rseq_after_asm_goto();
413481 return 0;
414482 abort:
483
+ rseq_after_asm_goto();
415484 RSEQ_INJECT_FAILED
416485 return -1;
417486 cmpfail:
487
+ rseq_after_asm_goto();
418488 return 1;
419489 #ifdef RSEQ_COMPARE_TWICE
420490 error1:
491
+ rseq_after_asm_goto();
421492 rseq_bug("cpu_id comparison failed");
422493 error2:
494
+ rseq_after_asm_goto();
423495 rseq_bug("expected value comparison failed");
424496 #endif
425497 }
....@@ -433,6 +505,12 @@
433505
434506 __asm__ __volatile__ goto (
435507 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
508
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
509
+#ifdef RSEQ_COMPARE_TWICE
510
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
511
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
512
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error3])
513
+#endif
436514 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
437515 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
438516 RSEQ_INJECT_ASM(3)
....@@ -450,8 +528,8 @@
450528 RSEQ_ASM_DEFINE_ABORT(4, abort)
451529 : /* gcc asm goto does not allow outputs */
452530 : [cpu_id] "r" (cpu),
453
- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
454
- [rseq_cs] "m" (__rseq_abi.rseq_cs),
531
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
532
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
455533 [v] "Qo" (*v),
456534 [expect] "r" (expect),
457535 [v2] "Qo" (*v2),
....@@ -464,19 +542,24 @@
464542 , error1, error2, error3
465543 #endif
466544 );
467
-
545
+ rseq_after_asm_goto();
468546 return 0;
469547 abort:
548
+ rseq_after_asm_goto();
470549 RSEQ_INJECT_FAILED
471550 return -1;
472551 cmpfail:
552
+ rseq_after_asm_goto();
473553 return 1;
474554 #ifdef RSEQ_COMPARE_TWICE
475555 error1:
556
+ rseq_after_asm_goto();
476557 rseq_bug("cpu_id comparison failed");
477558 error2:
559
+ rseq_after_asm_goto();
478560 rseq_bug("expected value comparison failed");
479561 error3:
562
+ rseq_after_asm_goto();
480563 rseq_bug("2nd expected value comparison failed");
481564 #endif
482565 }
....@@ -490,6 +573,11 @@
490573
491574 __asm__ __volatile__ goto (
492575 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
576
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
577
+#ifdef RSEQ_COMPARE_TWICE
578
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
579
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
580
+#endif
493581 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
494582 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
495583 RSEQ_INJECT_ASM(3)
....@@ -506,8 +594,8 @@
506594 RSEQ_ASM_DEFINE_ABORT(4, abort)
507595 : /* gcc asm goto does not allow outputs */
508596 : [cpu_id] "r" (cpu),
509
- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
510
- [rseq_cs] "m" (__rseq_abi.rseq_cs),
597
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
598
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
511599 [expect] "r" (expect),
512600 [v] "Qo" (*v),
513601 [newv] "r" (newv),
....@@ -521,17 +609,21 @@
521609 , error1, error2
522610 #endif
523611 );
524
-
612
+ rseq_after_asm_goto();
525613 return 0;
526614 abort:
615
+ rseq_after_asm_goto();
527616 RSEQ_INJECT_FAILED
528617 return -1;
529618 cmpfail:
619
+ rseq_after_asm_goto();
530620 return 1;
531621 #ifdef RSEQ_COMPARE_TWICE
532622 error1:
623
+ rseq_after_asm_goto();
533624 rseq_bug("cpu_id comparison failed");
534625 error2:
626
+ rseq_after_asm_goto();
535627 rseq_bug("expected value comparison failed");
536628 #endif
537629 }
....@@ -545,6 +637,11 @@
545637
546638 __asm__ __volatile__ goto (
547639 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
640
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
641
+#ifdef RSEQ_COMPARE_TWICE
642
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
643
+ RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
644
+#endif
548645 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
549646 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
550647 RSEQ_INJECT_ASM(3)
....@@ -561,8 +658,8 @@
561658 RSEQ_ASM_DEFINE_ABORT(4, abort)
562659 : /* gcc asm goto does not allow outputs */
563660 : [cpu_id] "r" (cpu),
564
- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
565
- [rseq_cs] "m" (__rseq_abi.rseq_cs),
661
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
662
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
566663 [expect] "r" (expect),
567664 [v] "Qo" (*v),
568665 [newv] "r" (newv),
....@@ -576,17 +673,21 @@
576673 , error1, error2
577674 #endif
578675 );
579
-
676
+ rseq_after_asm_goto();
580677 return 0;
581678 abort:
679
+ rseq_after_asm_goto();
582680 RSEQ_INJECT_FAILED
583681 return -1;
584682 cmpfail:
683
+ rseq_after_asm_goto();
585684 return 1;
586685 #ifdef RSEQ_COMPARE_TWICE
587686 error1:
687
+ rseq_after_asm_goto();
588688 rseq_bug("cpu_id comparison failed");
589689 error2:
690
+ rseq_after_asm_goto();
590691 rseq_bug("expected value comparison failed");
591692 #endif
592693 }