--- /dev/null
+From 889c5d60fbcf332c8b6ab7054d45f2768914a375 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Thu, 3 Feb 2022 10:05:32 -0500
+Subject: selftests/rseq: Change type of rseq_offset to ptrdiff_t
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 889c5d60fbcf332c8b6ab7054d45f2768914a375 upstream.
+
+Just before the 2.35 release of glibc, the __rseq_offset userspace ABI
+was changed from int to ptrdiff_t.
+
+Adapt to this change in the kernel selftests.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://sourceware.org/pipermail/libc-alpha/2022-February/136024.html
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-x86.h | 14 +++++++-------
+ tools/testing/selftests/rseq/rseq.c | 5 +++--
+ tools/testing/selftests/rseq/rseq.h | 3 ++-
+ 3 files changed, 12 insertions(+), 10 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq-x86.h
++++ b/tools/testing/selftests/rseq/rseq-x86.h
+@@ -143,7 +143,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_offset] "r" ((long)rseq_offset),
++ [rseq_offset] "r" (rseq_offset),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -214,7 +214,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_offset] "r" ((long)rseq_offset),
++ [rseq_offset] "r" (rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -270,7 +270,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_offset] "r" ((long)rseq_offset),
++ [rseq_offset] "r" (rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "er" (count)
+@@ -329,7 +329,7 @@ int rseq_offset_deref_addv(intptr_t *ptr
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_offset] "r" ((long)rseq_offset),
++ [rseq_offset] "r" (rseq_offset),
+ /* final store input */
+ [ptr] "m" (*ptr),
+ [off] "er" (off),
+@@ -387,7 +387,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_offset] "r" ((long)rseq_offset),
++ [rseq_offset] "r" (rseq_offset),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -469,7 +469,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_offset] "r" ((long)rseq_offset),
++ [rseq_offset] "r" (rseq_offset),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -581,7 +581,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ #endif
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_offset] "r" ((long)rseq_offset),
++ [rseq_offset] "r" (rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+--- a/tools/testing/selftests/rseq/rseq.c
++++ b/tools/testing/selftests/rseq/rseq.c
+@@ -27,16 +27,17 @@
+ #include <signal.h>
+ #include <limits.h>
+ #include <dlfcn.h>
++#include <stddef.h>
+
+ #include "../kselftest.h"
+ #include "rseq.h"
+
+-static const int *libc_rseq_offset_p;
++static const ptrdiff_t *libc_rseq_offset_p;
+ static const unsigned int *libc_rseq_size_p;
+ static const unsigned int *libc_rseq_flags_p;
+
+ /* Offset from the thread pointer to the rseq area. */
+-int rseq_offset;
++ptrdiff_t rseq_offset;
+
+ /* Size of the registered rseq area. 0 if the registration was
+ unsuccessful. */
+--- a/tools/testing/selftests/rseq/rseq.h
++++ b/tools/testing/selftests/rseq/rseq.h
+@@ -16,6 +16,7 @@
+ #include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <stddef.h>
+ #include "rseq-abi.h"
+ #include "compiler.h"
+
+@@ -47,7 +48,7 @@
+ #include "rseq-thread-pointer.h"
+
+ /* Offset from the thread pointer to the rseq area. */
+-extern int rseq_offset;
++extern ptrdiff_t rseq_offset;
+ /* Size of the registered rseq area. 0 if the registration was
+ unsuccessful. */
+ extern unsigned int rseq_size;
--- /dev/null
+From de6b52a21420a18dc8a36438d581efd1313d5fe3 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:47 -0500
+Subject: selftests/rseq: Fix ppc32 missing instruction selection "u" and "x" for load/store
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit de6b52a21420a18dc8a36438d581efd1313d5fe3 upstream.
+
+Building the rseq basic test with
+gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)
+Target: powerpc-linux-gnu
+
+leads to these errors:
+
+/tmp/ccieEWxU.s: Assembler messages:
+/tmp/ccieEWxU.s:118: Error: syntax error; found `,', expected `('
+/tmp/ccieEWxU.s:118: Error: junk at end of line: `,8'
+/tmp/ccieEWxU.s:121: Error: syntax error; found `,', expected `('
+/tmp/ccieEWxU.s:121: Error: junk at end of line: `,8'
+/tmp/ccieEWxU.s:626: Error: syntax error; found `,', expected `('
+/tmp/ccieEWxU.s:626: Error: junk at end of line: `,8'
+/tmp/ccieEWxU.s:629: Error: syntax error; found `,', expected `('
+/tmp/ccieEWxU.s:629: Error: junk at end of line: `,8'
+/tmp/ccieEWxU.s:735: Error: syntax error; found `,', expected `('
+/tmp/ccieEWxU.s:735: Error: junk at end of line: `,8'
+/tmp/ccieEWxU.s:738: Error: syntax error; found `,', expected `('
+/tmp/ccieEWxU.s:738: Error: junk at end of line: `,8'
+/tmp/ccieEWxU.s:741: Error: syntax error; found `,', expected `('
+/tmp/ccieEWxU.s:741: Error: junk at end of line: `,8'
+Makefile:581: recipe for target 'basic_percpu_ops_test.o' failed
+
+Based on discussion with Linux powerpc maintainers and review of
+the use of the "m" operand in powerpc kernel code, add the missing
+%Un%Xn (where n is operand number) to the lwz, stw, ld, and std
+instructions when used with "m" operands.
+
+Using "WORD" to mean either a 32-bit or 64-bit type depending on
+the architecture is misleading. The term "WORD" really means a
+32-bit type in both 32-bit and 64-bit powerpc assembler. The intent
+here is to wrap load/store to intptr_t into common macros for both
+32-bit and 64-bit.
+
+Rename the macros with a RSEQ_ prefix, and use the terms "INT"
+for always 32-bit type, and "LONG" for architecture bitness-sized
+type.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-10-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-ppc.h | 55 ++++++++++++++++----------------
+ 1 file changed, 28 insertions(+), 27 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq-ppc.h
++++ b/tools/testing/selftests/rseq/rseq-ppc.h
+@@ -47,10 +47,13 @@ do { \
+
+ #ifdef __PPC64__
+
+-#define STORE_WORD "std "
+-#define LOAD_WORD "ld "
+-#define LOADX_WORD "ldx "
+-#define CMP_WORD "cmpd "
++#define RSEQ_STORE_LONG(arg) "std%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* To memory ("m" constraint) */
++#define RSEQ_STORE_INT(arg) "stw%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* To memory ("m" constraint) */
++#define RSEQ_LOAD_LONG(arg) "ld%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* From memory ("m" constraint) */
++#define RSEQ_LOAD_INT(arg) "lwz%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* From memory ("m" constraint) */
++#define RSEQ_LOADX_LONG "ldx " /* From base register ("b" constraint) */
++#define RSEQ_CMP_LONG "cmpd "
++#define RSEQ_CMP_LONG_INT "cmpdi "
+
+ #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
+ start_ip, post_commit_offset, abort_ip) \
+@@ -89,10 +92,13 @@ do { \
+
+ #else /* #ifdef __PPC64__ */
+
+-#define STORE_WORD "stw "
+-#define LOAD_WORD "lwz "
+-#define LOADX_WORD "lwzx "
+-#define CMP_WORD "cmpw "
++#define RSEQ_STORE_LONG(arg) "stw%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* To memory ("m" constraint) */
++#define RSEQ_STORE_INT(arg) RSEQ_STORE_LONG(arg) /* To memory ("m" constraint) */
++#define RSEQ_LOAD_LONG(arg) "lwz%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* From memory ("m" constraint) */
++#define RSEQ_LOAD_INT(arg) RSEQ_LOAD_LONG(arg) /* From memory ("m" constraint) */
++#define RSEQ_LOADX_LONG "lwzx " /* From base register ("b" constraint) */
++#define RSEQ_CMP_LONG "cmpw "
++#define RSEQ_CMP_LONG_INT "cmpwi "
+
+ #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
+ start_ip, post_commit_offset, abort_ip) \
+@@ -125,7 +131,7 @@ do { \
+ RSEQ_INJECT_ASM(1) \
+ "lis %%r17, (" __rseq_str(cs_label) ")@ha\n\t" \
+ "addi %%r17, %%r17, (" __rseq_str(cs_label) ")@l\n\t" \
+- "stw %%r17, %[" __rseq_str(rseq_cs) "]\n\t" \
++ RSEQ_STORE_INT(rseq_cs) "%%r17, %[" __rseq_str(rseq_cs) "]\n\t" \
+ __rseq_str(label) ":\n\t"
+
+ #endif /* #ifdef __PPC64__ */
+@@ -136,7 +142,7 @@ do { \
+
+ #define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label) \
+ RSEQ_INJECT_ASM(2) \
+- "lwz %%r17, %[" __rseq_str(current_cpu_id) "]\n\t" \
++ RSEQ_LOAD_INT(current_cpu_id) "%%r17, %[" __rseq_str(current_cpu_id) "]\n\t" \
+ "cmpw cr7, %[" __rseq_str(cpu_id) "], %%r17\n\t" \
+ "bne- cr7, " __rseq_str(label) "\n\t"
+
+@@ -153,25 +159,25 @@ do { \
+ * RSEQ_ASM_OP_* (else): doesn't have hard-code registers(unless cr7)
+ */
+ #define RSEQ_ASM_OP_CMPEQ(var, expect, label) \
+- LOAD_WORD "%%r17, %[" __rseq_str(var) "]\n\t" \
+- CMP_WORD "cr7, %%r17, %[" __rseq_str(expect) "]\n\t" \
++ RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t" \
++ RSEQ_CMP_LONG "cr7, %%r17, %[" __rseq_str(expect) "]\n\t" \
+ "bne- cr7, " __rseq_str(label) "\n\t"
+
+ #define RSEQ_ASM_OP_CMPNE(var, expectnot, label) \
+- LOAD_WORD "%%r17, %[" __rseq_str(var) "]\n\t" \
+- CMP_WORD "cr7, %%r17, %[" __rseq_str(expectnot) "]\n\t" \
++ RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t" \
++ RSEQ_CMP_LONG "cr7, %%r17, %[" __rseq_str(expectnot) "]\n\t" \
+ "beq- cr7, " __rseq_str(label) "\n\t"
+
+ #define RSEQ_ASM_OP_STORE(value, var) \
+- STORE_WORD "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t"
++ RSEQ_STORE_LONG(var) "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t"
+
+ /* Load @var to r17 */
+ #define RSEQ_ASM_OP_R_LOAD(var) \
+- LOAD_WORD "%%r17, %[" __rseq_str(var) "]\n\t"
++ RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"
+
+ /* Store r17 to @var */
+ #define RSEQ_ASM_OP_R_STORE(var) \
+- STORE_WORD "%%r17, %[" __rseq_str(var) "]\n\t"
++ RSEQ_STORE_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"
+
+ /* Add @count to r17 */
+ #define RSEQ_ASM_OP_R_ADD(count) \
+@@ -179,11 +185,11 @@ do { \
+
+ /* Load (r17 + voffp) to r17 */
+ #define RSEQ_ASM_OP_R_LOADX(voffp) \
+- LOADX_WORD "%%r17, %[" __rseq_str(voffp) "], %%r17\n\t"
++ RSEQ_LOADX_LONG "%%r17, %[" __rseq_str(voffp) "], %%r17\n\t"
+
+ /* TODO: implement a faster memcpy. */
+ #define RSEQ_ASM_OP_R_MEMCPY() \
+- "cmpdi %%r19, 0\n\t" \
++ RSEQ_CMP_LONG_INT "%%r19, 0\n\t" \
+ "beq 333f\n\t" \
+ "addi %%r20, %%r20, -1\n\t" \
+ "addi %%r21, %%r21, -1\n\t" \
+@@ -191,16 +197,16 @@ do { \
+ "lbzu %%r18, 1(%%r20)\n\t" \
+ "stbu %%r18, 1(%%r21)\n\t" \
+ "addi %%r19, %%r19, -1\n\t" \
+- "cmpdi %%r19, 0\n\t" \
++ RSEQ_CMP_LONG_INT "%%r19, 0\n\t" \
+ "bne 222b\n\t" \
+ "333:\n\t" \
+
+ #define RSEQ_ASM_OP_R_FINAL_STORE(var, post_commit_label) \
+- STORE_WORD "%%r17, %[" __rseq_str(var) "]\n\t" \
++ RSEQ_STORE_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t" \
+ __rseq_str(post_commit_label) ":\n\t"
+
+ #define RSEQ_ASM_OP_FINAL_STORE(value, var, post_commit_label) \
+- STORE_WORD "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t" \
++ RSEQ_STORE_LONG(var) "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t" \
+ __rseq_str(post_commit_label) ":\n\t"
+
+ static inline __attribute__((always_inline))
+@@ -743,9 +749,4 @@ error2:
+ #endif
+ }
+
+-#undef STORE_WORD
+-#undef LOAD_WORD
+-#undef LOADX_WORD
+-#undef CMP_WORD
+-
+ #endif /* !RSEQ_SKIP_FASTPATH */
--- /dev/null
+From 26dc8a6d8e11552f3b797b5aafe01071ca32d692 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:48 -0500
+Subject: selftests/rseq: Fix ppc32 offsets by using long rather than off_t
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 26dc8a6d8e11552f3b797b5aafe01071ca32d692 upstream.
+
+The semantic of off_t is for file offsets. We mean to use it as an
+offset from a pointer. We really expect it to fit in a single register,
+and not use a 64-bit type on 32-bit architectures.
+
+Fix runtime issues on ppc32 where the offset is always 0 due to
+inconsistency between the argument type (off_t -> 64-bit) and type
+expected by the inline assembler (32-bit).
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-11-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/basic_percpu_ops_test.c | 2 +-
+ tools/testing/selftests/rseq/param_test.c | 2 +-
+ tools/testing/selftests/rseq/rseq-arm.h | 2 +-
+ tools/testing/selftests/rseq/rseq-arm64.h | 2 +-
+ tools/testing/selftests/rseq/rseq-mips.h | 2 +-
+ tools/testing/selftests/rseq/rseq-ppc.h | 2 +-
+ tools/testing/selftests/rseq/rseq-s390.h | 2 +-
+ tools/testing/selftests/rseq/rseq-skip.h | 2 +-
+ tools/testing/selftests/rseq/rseq-x86.h | 6 +++---
+ 9 files changed, 11 insertions(+), 11 deletions(-)
+
+--- a/tools/testing/selftests/rseq/basic_percpu_ops_test.c
++++ b/tools/testing/selftests/rseq/basic_percpu_ops_test.c
+@@ -167,7 +167,7 @@ struct percpu_list_node *this_cpu_list_p
+ for (;;) {
+ struct percpu_list_node *head;
+ intptr_t *targetptr, expectnot, *load;
+- off_t offset;
++ long offset;
+ int ret, cpu;
+
+ cpu = rseq_cpu_start();
+--- a/tools/testing/selftests/rseq/param_test.c
++++ b/tools/testing/selftests/rseq/param_test.c
+@@ -549,7 +549,7 @@ struct percpu_list_node *this_cpu_list_p
+ for (;;) {
+ struct percpu_list_node *head;
+ intptr_t *targetptr, expectnot, *load;
+- off_t offset;
++ long offset;
+ int ret;
+
+ cpu = rseq_cpu_start();
+--- a/tools/testing/selftests/rseq/rseq-arm.h
++++ b/tools/testing/selftests/rseq/rseq-arm.h
+@@ -217,7 +217,7 @@ error2:
+
+ static inline __attribute__((always_inline))
+ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
+- off_t voffp, intptr_t *load, int cpu)
++ long voffp, intptr_t *load, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+--- a/tools/testing/selftests/rseq/rseq-arm64.h
++++ b/tools/testing/selftests/rseq/rseq-arm64.h
+@@ -259,7 +259,7 @@ error2:
+
+ static inline __attribute__((always_inline))
+ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
+- off_t voffp, intptr_t *load, int cpu)
++ long voffp, intptr_t *load, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+--- a/tools/testing/selftests/rseq/rseq-mips.h
++++ b/tools/testing/selftests/rseq/rseq-mips.h
+@@ -222,7 +222,7 @@ error2:
+
+ static inline __attribute__((always_inline))
+ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
+- off_t voffp, intptr_t *load, int cpu)
++ long voffp, intptr_t *load, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+--- a/tools/testing/selftests/rseq/rseq-ppc.h
++++ b/tools/testing/selftests/rseq/rseq-ppc.h
+@@ -270,7 +270,7 @@ error2:
+
+ static inline __attribute__((always_inline))
+ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
+- off_t voffp, intptr_t *load, int cpu)
++ long voffp, intptr_t *load, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+--- a/tools/testing/selftests/rseq/rseq-s390.h
++++ b/tools/testing/selftests/rseq/rseq-s390.h
+@@ -198,7 +198,7 @@ error2:
+ */
+ static inline __attribute__((always_inline))
+ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
+- off_t voffp, intptr_t *load, int cpu)
++ long voffp, intptr_t *load, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+--- a/tools/testing/selftests/rseq/rseq-skip.h
++++ b/tools/testing/selftests/rseq/rseq-skip.h
+@@ -13,7 +13,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+
+ static inline __attribute__((always_inline))
+ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
+- off_t voffp, intptr_t *load, int cpu)
++ long voffp, intptr_t *load, int cpu)
+ {
+ return -1;
+ }
+--- a/tools/testing/selftests/rseq/rseq-x86.h
++++ b/tools/testing/selftests/rseq/rseq-x86.h
+@@ -172,7 +172,7 @@ error2:
+ */
+ static inline __attribute__((always_inline))
+ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
+- off_t voffp, intptr_t *load, int cpu)
++ long voffp, intptr_t *load, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+@@ -286,7 +286,7 @@ error1:
+ * *pval += inc;
+ */
+ static inline __attribute__((always_inline))
+-int rseq_offset_deref_addv(intptr_t *ptr, off_t off, intptr_t inc, int cpu)
++int rseq_offset_deref_addv(intptr_t *ptr, long off, intptr_t inc, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+@@ -750,7 +750,7 @@ error2:
+ */
+ static inline __attribute__((always_inline))
+ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
+- off_t voffp, intptr_t *load, int cpu)
++ long voffp, intptr_t *load, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
--- /dev/null
+From 24d1136a29da5953de5c0cbc6c83eb62a1e0bf14 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:46 -0500
+Subject: selftests/rseq: Fix ppc32: wrong rseq_cs 32-bit field pointer on big endian
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 24d1136a29da5953de5c0cbc6c83eb62a1e0bf14 upstream.
+
+ppc32 incorrectly uses padding as rseq_cs pointer field. Fix this by
+using the rseq_cs.arch.ptr field.
+
+Use this field across all architectures.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-9-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-arm.h | 16 ++++++++--------
+ tools/testing/selftests/rseq/rseq-arm64.h | 16 ++++++++--------
+ tools/testing/selftests/rseq/rseq-mips.h | 16 ++++++++--------
+ tools/testing/selftests/rseq/rseq-ppc.h | 16 ++++++++--------
+ tools/testing/selftests/rseq/rseq-s390.h | 12 ++++++------
+ 5 files changed, 38 insertions(+), 38 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq-arm.h
++++ b/tools/testing/selftests/rseq/rseq-arm.h
+@@ -186,7 +186,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -256,7 +256,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -317,7 +317,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "m" (*v),
+ [count] "Ir" (count)
+ RSEQ_INJECT_INPUT
+@@ -382,7 +382,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -458,7 +458,7 @@ int rseq_cmpeqv_trystorev_storev_release
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -538,7 +538,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -658,7 +658,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+@@ -783,7 +783,7 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+--- a/tools/testing/selftests/rseq/rseq-arm64.h
++++ b/tools/testing/selftests/rseq/rseq-arm64.h
+@@ -231,7 +231,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "Qo" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -288,7 +288,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "Qo" (*v),
+ [expectnot] "r" (expectnot),
+ [load] "Qo" (*load),
+@@ -338,7 +338,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "Qo" (*v),
+ [count] "r" (count)
+ RSEQ_INJECT_INPUT
+@@ -389,7 +389,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [expect] "r" (expect),
+ [v] "Qo" (*v),
+ [newv] "r" (newv),
+@@ -448,7 +448,7 @@ int rseq_cmpeqv_trystorev_storev_release
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [expect] "r" (expect),
+ [v] "Qo" (*v),
+ [newv] "r" (newv),
+@@ -509,7 +509,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "Qo" (*v),
+ [expect] "r" (expect),
+ [v2] "Qo" (*v2),
+@@ -570,7 +570,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [expect] "r" (expect),
+ [v] "Qo" (*v),
+ [newv] "r" (newv),
+@@ -630,7 +630,7 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [expect] "r" (expect),
+ [v] "Qo" (*v),
+ [newv] "r" (newv),
+--- a/tools/testing/selftests/rseq/rseq-mips.h
++++ b/tools/testing/selftests/rseq/rseq-mips.h
+@@ -191,7 +191,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -259,7 +259,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -320,7 +320,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "m" (*v),
+ [count] "Ir" (count)
+ RSEQ_INJECT_INPUT
+@@ -383,7 +383,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -457,7 +457,7 @@ int rseq_cmpeqv_trystorev_storev_release
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -533,7 +533,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -650,7 +650,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+@@ -772,7 +772,7 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+--- a/tools/testing/selftests/rseq/rseq-ppc.h
++++ b/tools/testing/selftests/rseq/rseq-ppc.h
+@@ -236,7 +236,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -302,7 +302,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -360,7 +360,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "r" (count)
+@@ -420,7 +420,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -490,7 +490,7 @@ int rseq_cmpeqv_trystorev_storev_release
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -561,7 +561,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -636,7 +636,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+@@ -712,7 +712,7 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+--- a/tools/testing/selftests/rseq/rseq-s390.h
++++ b/tools/testing/selftests/rseq/rseq-s390.h
+@@ -166,7 +166,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -234,7 +234,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -289,7 +289,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "r" (count)
+@@ -348,7 +348,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -427,7 +427,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -535,7 +535,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
+- [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
--- /dev/null
+From d7ed99ade3e62b755584eea07b4e499e79240527 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:49 -0500
+Subject: selftests/rseq: Fix warnings about #if checks of undefined tokens
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit d7ed99ade3e62b755584eea07b4e499e79240527 upstream.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-12-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/param_test.c | 2 +-
+ tools/testing/selftests/rseq/rseq-x86.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/tools/testing/selftests/rseq/param_test.c
++++ b/tools/testing/selftests/rseq/param_test.c
+@@ -161,7 +161,7 @@ unsigned int yield_mod_cnt, nr_abort;
+ " cbnz " INJECT_ASM_REG ", 222b\n" \
+ "333:\n"
+
+-#elif __PPC__
++#elif defined(__PPC__)
+
+ #define RSEQ_INJECT_INPUT \
+ , [loop_cnt_1]"m"(loop_cnt[1]) \
+--- a/tools/testing/selftests/rseq/rseq-x86.h
++++ b/tools/testing/selftests/rseq/rseq-x86.h
+@@ -600,7 +600,7 @@ int rseq_cmpeqv_trymemcpy_storev_release
+
+ #endif /* !RSEQ_SKIP_FASTPATH */
+
+-#elif __i386__
++#elif defined(__i386__)
+
+ #define rseq_smp_mb() \
+ __asm__ __volatile__ ("lock; addl $0,-128(%%esp)" ::: "memory", "cc")
--- /dev/null
+From b53823fb2ef854222853be164f3b1e815f315144 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:51 -0500
+Subject: selftests/rseq: Fix: work-around asm goto compiler bugs
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit b53823fb2ef854222853be164f3b1e815f315144 upstream.
+
+gcc and clang each have their own compiler bugs with respect to asm
+goto. Implement a work-around for compiler versions known to have those
+bugs.
+
+gcc prior to 4.8.2 miscompiles asm goto.
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+
+gcc prior to 8.1.0 miscompiles asm goto at O1.
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103908
+
+clang prior to version 13.0.1 miscompiles asm goto at O2.
+https://github.com/llvm/llvm-project/issues/52735
+
+Work around these issues by adding a volatile inline asm with
+memory clobber in the fallthrough after the asm goto and at each
+label target. Emit this for all compilers in case other similar
+issues are found in the future.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-14-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/compiler.h | 30 +++++++++++++
+ tools/testing/selftests/rseq/rseq-arm.h | 39 +++++++++++++++++
+ tools/testing/selftests/rseq/rseq-arm64.h | 45 +++++++++++++++++--
+ tools/testing/selftests/rseq/rseq-ppc.h | 39 +++++++++++++++++
+ tools/testing/selftests/rseq/rseq-s390.h | 29 ++++++++++++
+ tools/testing/selftests/rseq/rseq-x86.h | 68 ++++++++++++++++++++++++++++++
+ tools/testing/selftests/rseq/rseq.h | 1
+ 7 files changed, 245 insertions(+), 6 deletions(-)
+ create mode 100644 tools/testing/selftests/rseq/compiler.h
+
+--- /dev/null
++++ b/tools/testing/selftests/rseq/compiler.h
+@@ -0,0 +1,30 @@
++/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */
++/*
++ * rseq/compiler.h
++ *
++ * Work-around asm goto compiler bugs.
++ *
++ * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ */
++
++#ifndef RSEQ_COMPILER_H
++#define RSEQ_COMPILER_H
++
++/*
++ * gcc prior to 4.8.2 miscompiles asm goto.
++ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
++ *
++ * gcc prior to 8.1.0 miscompiles asm goto at O1.
++ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103908
++ *
++ * clang prior to version 13.0.1 miscompiles asm goto at O2.
++ * https://github.com/llvm/llvm-project/issues/52735
++ *
++ * Work around these issues by adding a volatile inline asm with
++ * memory clobber in the fallthrough after the asm goto and at each
++ * label target. Emit this for all compilers in case other similar
++ * issues are found in the future.
++ */
++#define rseq_after_asm_goto() asm volatile ("" : : : "memory")
++
++#endif /* RSEQ_COMPILER_H_ */
+--- a/tools/testing/selftests/rseq/rseq-arm.h
++++ b/tools/testing/selftests/rseq/rseq-arm.h
+@@ -195,16 +195,21 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -263,16 +268,21 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -317,12 +327,15 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ , error1
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ #endif
+ }
+@@ -384,16 +397,21 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -456,16 +474,21 @@ int rseq_cmpeqv_trystorev_storev_release
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -532,18 +555,24 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ , error1, error2, error3
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("1st expected value comparison failed");
+ error3:
++ rseq_after_asm_goto();
+ rseq_bug("2nd expected value comparison failed");
+ #endif
+ }
+@@ -652,16 +681,21 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -771,16 +805,21 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+--- a/tools/testing/selftests/rseq/rseq-arm64.h
++++ b/tools/testing/selftests/rseq/rseq-arm64.h
+@@ -242,17 +242,21 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ , error1, error2
+ #endif
+ );
+-
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -300,16 +304,21 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -348,12 +357,15 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ , error1
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ #endif
+ }
+@@ -402,17 +414,21 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ , error1, error2
+ #endif
+ );
+-
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -461,17 +477,21 @@ int rseq_cmpeqv_trystorev_storev_release
+ , error1, error2
+ #endif
+ );
+-
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -522,19 +542,24 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ , error1, error2, error3
+ #endif
+ );
+-
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ error3:
++ rseq_after_asm_goto();
+ rseq_bug("2nd expected value comparison failed");
+ #endif
+ }
+@@ -584,17 +609,21 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ , error1, error2
+ #endif
+ );
+-
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -644,17 +673,21 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ , error1, error2
+ #endif
+ );
+-
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+--- a/tools/testing/selftests/rseq/rseq-ppc.h
++++ b/tools/testing/selftests/rseq/rseq-ppc.h
+@@ -254,16 +254,21 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -322,16 +327,21 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -378,12 +388,15 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ , error1
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ #endif
+ }
+@@ -442,16 +455,21 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -512,16 +530,21 @@ int rseq_cmpeqv_trystorev_storev_release
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -583,18 +606,24 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ , error1, error2, error3
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("1st expected value comparison failed");
+ error3:
++ rseq_after_asm_goto();
+ rseq_bug("2nd expected value comparison failed");
+ #endif
+ }
+@@ -659,16 +688,21 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -735,16 +769,21 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+--- a/tools/testing/selftests/rseq/rseq-s390.h
++++ b/tools/testing/selftests/rseq/rseq-s390.h
+@@ -178,16 +178,21 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -248,16 +253,21 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -301,12 +311,15 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ , error1
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ #endif
+ }
+@@ -364,16 +377,21 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -443,18 +461,24 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ , error1, error2, error3
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("1st expected value comparison failed");
+ error3:
++ rseq_after_asm_goto();
+ rseq_bug("2nd expected value comparison failed");
+ #endif
+ }
+@@ -555,16 +579,21 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+--- a/tools/testing/selftests/rseq/rseq-x86.h
++++ b/tools/testing/selftests/rseq/rseq-x86.h
+@@ -152,16 +152,21 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -220,16 +225,21 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -269,12 +279,15 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ , error1
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ #endif
+ }
+@@ -387,16 +400,21 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -464,18 +482,24 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ , error1, error2, error3
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("1st expected value comparison failed");
+ error3:
++ rseq_after_asm_goto();
+ rseq_bug("2nd expected value comparison failed");
+ #endif
+ }
+@@ -574,16 +598,21 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -730,16 +759,21 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -798,16 +832,21 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -847,12 +886,15 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ , error1
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ #endif
+ }
+@@ -909,16 +951,21 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -977,16 +1024,21 @@ int rseq_cmpeqv_trystorev_storev_release
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+
+@@ -1047,18 +1099,24 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ , error1, error2, error3
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("1st expected value comparison failed");
+ error3:
++ rseq_after_asm_goto();
+ rseq_bug("2nd expected value comparison failed");
+ #endif
+ }
+@@ -1161,16 +1219,21 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -1274,16 +1337,21 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ , error1, error2
+ #endif
+ );
++ rseq_after_asm_goto();
+ return 0;
+ abort:
++ rseq_after_asm_goto();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
++ rseq_after_asm_goto();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
++ rseq_after_asm_goto();
+ rseq_bug("cpu_id comparison failed");
+ error2:
++ rseq_after_asm_goto();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+--- a/tools/testing/selftests/rseq/rseq.h
++++ b/tools/testing/selftests/rseq/rseq.h
+@@ -17,6 +17,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include "rseq-abi.h"
++#include "compiler.h"
+
+ /*
+ * Empty code injection macros, override when testing.
--- /dev/null
+From 5c105d55a9dc9e01535116ccfc26e703168a574f Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:39 -0500
+Subject: selftests/rseq: introduce own copy of rseq uapi header
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 5c105d55a9dc9e01535116ccfc26e703168a574f upstream.
+
+The Linux kernel rseq uapi header has a broken layout for the
+rseq_cs.ptr field on 32-bit little endian architectures. The entire
+rseq_cs.ptr field is planned for removal, leaving only the 64-bit
+rseq_cs.ptr64 field available.
+
+Both glibc and librseq use their own copy of the Linux kernel uapi
+header, where they introduce proper union fields to access to the 32-bit
+low order bits of the rseq_cs pointer on 32-bit architectures.
+
+Introduce a copy of the Linux kernel uapi headers in the Linux kernel
+selftests.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-2-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-abi.h | 151 ++++++++++++++++++++++++++++++++
+ tools/testing/selftests/rseq/rseq.c | 14 +-
+ tools/testing/selftests/rseq/rseq.h | 10 --
+ 3 files changed, 161 insertions(+), 14 deletions(-)
+ create mode 100644 tools/testing/selftests/rseq/rseq-abi.h
+
+--- /dev/null
++++ b/tools/testing/selftests/rseq/rseq-abi.h
+@@ -0,0 +1,151 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++#ifndef _RSEQ_ABI_H
++#define _RSEQ_ABI_H
++
++/*
++ * rseq-abi.h
++ *
++ * Restartable sequences system call API
++ *
++ * Copyright (c) 2015-2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ */
++
++#include <linux/types.h>
++#include <asm/byteorder.h>
++
++enum rseq_abi_cpu_id_state {
++ RSEQ_ABI_CPU_ID_UNINITIALIZED = -1,
++ RSEQ_ABI_CPU_ID_REGISTRATION_FAILED = -2,
++};
++
++enum rseq_abi_flags {
++ RSEQ_ABI_FLAG_UNREGISTER = (1 << 0),
++};
++
++enum rseq_abi_cs_flags_bit {
++ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0,
++ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1,
++ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2,
++};
++
++enum rseq_abi_cs_flags {
++ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT =
++ (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT),
++ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL =
++ (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT),
++ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE =
++ (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT),
++};
++
++/*
++ * struct rseq_abi_cs is aligned on 4 * 8 bytes to ensure it is always
++ * contained within a single cache-line. It is usually declared as
++ * link-time constant data.
++ */
++struct rseq_abi_cs {
++ /* Version of this structure. */
++ __u32 version;
++ /* enum rseq_abi_cs_flags */
++ __u32 flags;
++ __u64 start_ip;
++ /* Offset from start_ip. */
++ __u64 post_commit_offset;
++ __u64 abort_ip;
++} __attribute__((aligned(4 * sizeof(__u64))));
++
++/*
++ * struct rseq_abi is aligned on 4 * 8 bytes to ensure it is always
++ * contained within a single cache-line.
++ *
++ * A single struct rseq_abi per thread is allowed.
++ */
++struct rseq_abi {
++ /*
++ * Restartable sequences cpu_id_start field. Updated by the
++ * kernel. Read by user-space with single-copy atomicity
++ * semantics. This field should only be read by the thread which
++ * registered this data structure. Aligned on 32-bit. Always
++ * contains a value in the range of possible CPUs, although the
++ * value may not be the actual current CPU (e.g. if rseq is not
++ * initialized). This CPU number value should always be compared
++ * against the value of the cpu_id field before performing a rseq
++ * commit or returning a value read from a data structure indexed
++ * using the cpu_id_start value.
++ */
++ __u32 cpu_id_start;
++ /*
++ * Restartable sequences cpu_id field. Updated by the kernel.
++ * Read by user-space with single-copy atomicity semantics. This
++ * field should only be read by the thread which registered this
++ * data structure. Aligned on 32-bit. Values
++ * RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED
++ * have a special semantic: the former means "rseq uninitialized",
++ * and latter means "rseq initialization failed". This value is
++ * meant to be read within rseq critical sections and compared
++ * with the cpu_id_start value previously read, before performing
++ * the commit instruction, or read and compared with the
++ * cpu_id_start value before returning a value loaded from a data
++ * structure indexed using the cpu_id_start value.
++ */
++ __u32 cpu_id;
++ /*
++ * Restartable sequences rseq_cs field.
++ *
++ * Contains NULL when no critical section is active for the current
++ * thread, or holds a pointer to the currently active struct rseq_cs.
++ *
++ * Updated by user-space, which sets the address of the currently
++ * active rseq_cs at the beginning of assembly instruction sequence
++ * block, and set to NULL by the kernel when it restarts an assembly
++ * instruction sequence block, as well as when the kernel detects that
++ * it is preempting or delivering a signal outside of the range
++ * targeted by the rseq_cs. Also needs to be set to NULL by user-space
++ * before reclaiming memory that contains the targeted struct rseq_cs.
++ *
++ * Read and set by the kernel. Set by user-space with single-copy
++ * atomicity semantics. This field should only be updated by the
++ * thread which registered this data structure. Aligned on 64-bit.
++ */
++ union {
++ __u64 ptr64;
++
++ /*
++ * The "arch" field provides architecture accessor for
++ * the ptr field based on architecture pointer size and
++ * endianness.
++ */
++ struct {
++#ifdef __LP64__
++ __u64 ptr;
++#elif defined(__BYTE_ORDER) ? (__BYTE_ORDER == __BIG_ENDIAN) : defined(__BIG_ENDIAN)
++ __u32 padding; /* Initialized to zero. */
++ __u32 ptr;
++#else
++ __u32 ptr;
++ __u32 padding; /* Initialized to zero. */
++#endif
++ } arch;
++ } rseq_cs;
++
++ /*
++ * Restartable sequences flags field.
++ *
++ * This field should only be updated by the thread which
++ * registered this data structure. Read by the kernel.
++ * Mainly used for single-stepping through rseq critical sections
++ * with debuggers.
++ *
++ * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT
++ * Inhibit instruction sequence block restart on preemption
++ * for this thread.
++ * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL
++ * Inhibit instruction sequence block restart on signal
++ * delivery for this thread.
++ * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE
++ * Inhibit instruction sequence block restart on migration for
++ * this thread.
++ */
++ __u32 flags;
++} __attribute__((aligned(4 * sizeof(__u64))));
++
++#endif /* _RSEQ_ABI_H */
+--- a/tools/testing/selftests/rseq/rseq.c
++++ b/tools/testing/selftests/rseq/rseq.c
+@@ -30,8 +30,8 @@
+ #include "../kselftest.h"
+ #include "rseq.h"
+
+-__thread volatile struct rseq __rseq_abi = {
+- .cpu_id = RSEQ_CPU_ID_UNINITIALIZED,
++__thread volatile struct rseq_abi __rseq_abi = {
++ .cpu_id = RSEQ_ABI_CPU_ID_UNINITIALIZED,
+ };
+
+ /*
+@@ -66,7 +66,7 @@ static void signal_restore(sigset_t olds
+ abort();
+ }
+
+-static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len,
++static int sys_rseq(volatile struct rseq_abi *rseq_abi, uint32_t rseq_len,
+ int flags, uint32_t sig)
+ {
+ return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig);
+@@ -86,13 +86,13 @@ int rseq_register_current_thread(void)
+ }
+ if (__rseq_refcount++)
+ goto end;
+- rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 0, RSEQ_SIG);
++ rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), 0, RSEQ_SIG);
+ if (!rc) {
+ assert(rseq_current_cpu_raw() >= 0);
+ goto end;
+ }
+ if (errno != EBUSY)
+- __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
++ __rseq_abi.cpu_id = RSEQ_ABI_CPU_ID_REGISTRATION_FAILED;
+ ret = -1;
+ __rseq_refcount--;
+ end:
+@@ -114,8 +114,8 @@ int rseq_unregister_current_thread(void)
+ }
+ if (--__rseq_refcount)
+ goto end;
+- rc = sys_rseq(&__rseq_abi, sizeof(struct rseq),
+- RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
++ rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi),
++ RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG);
+ if (!rc)
+ goto end;
+ __rseq_refcount = 1;
+--- a/tools/testing/selftests/rseq/rseq.h
++++ b/tools/testing/selftests/rseq/rseq.h
+@@ -16,7 +16,7 @@
+ #include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+-#include <linux/rseq.h>
++#include "rseq-abi.h"
+
+ /*
+ * Empty code injection macros, override when testing.
+@@ -43,7 +43,7 @@
+ #define RSEQ_INJECT_FAILED
+ #endif
+
+-extern __thread volatile struct rseq __rseq_abi;
++extern __thread volatile struct rseq_abi __rseq_abi;
+ extern int __rseq_handled;
+
+ #define rseq_likely(x) __builtin_expect(!!(x), 1)
+@@ -139,11 +139,7 @@ static inline uint32_t rseq_current_cpu(
+
+ static inline void rseq_clear_rseq_cs(void)
+ {
+-#ifdef __LP64__
+- __rseq_abi.rseq_cs.ptr = 0;
+-#else
+- __rseq_abi.rseq_cs.ptr.ptr32 = 0;
+-#endif
++ __rseq_abi.rseq_cs.arch.ptr = 0;
+ }
+
+ /*
--- /dev/null
+From e546cd48ccc456074ddb8920732aef4af65d7ca7 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:43 -0500
+Subject: selftests/rseq: Introduce rseq_get_abi() helper
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit e546cd48ccc456074ddb8920732aef4af65d7ca7 upstream.
+
+This is done in preparation for the selftest uplift to become compatible
+with glibc-2.35.
+
+glibc-2.35 exposes the rseq per-thread data in the TCB, accessible
+at an offset from the thread pointer, rather than through an actual
+Thread-Local Storage (TLS) variable, as the kernel selftests initially
+expected.
+
+Introduce a rseq_get_abi() helper, initially using the __rseq_abi
+TLS variable, in preparation for changing this userspace ABI for one
+which is compatible with glibc-2.35.
+
+Note that the __rseq_abi TLS and glibc-2.35's ABI for per-thread data
+cannot actively coexist in a process, because the kernel supports only
+a single rseq registration per thread.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-6-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-arm.h | 32 +++++++++++++++---------------
+ tools/testing/selftests/rseq/rseq-arm64.h | 32 +++++++++++++++---------------
+ tools/testing/selftests/rseq/rseq-mips.h | 32 +++++++++++++++---------------
+ tools/testing/selftests/rseq/rseq-ppc.h | 32 +++++++++++++++---------------
+ tools/testing/selftests/rseq/rseq-s390.h | 24 +++++++++++-----------
+ tools/testing/selftests/rseq/rseq-x86.h | 30 ++++++++++++++--------------
+ tools/testing/selftests/rseq/rseq.h | 11 +++++++---
+ 7 files changed, 99 insertions(+), 94 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq-arm.h
++++ b/tools/testing/selftests/rseq/rseq-arm.h
+@@ -185,8 +185,8 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -255,8 +255,8 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -316,8 +316,8 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "m" (*v),
+ [count] "Ir" (count)
+ RSEQ_INJECT_INPUT
+@@ -381,8 +381,8 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -457,8 +457,8 @@ int rseq_cmpeqv_trystorev_storev_release
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -537,8 +537,8 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -657,8 +657,8 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ "8:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+@@ -782,8 +782,8 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ "8:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+--- a/tools/testing/selftests/rseq/rseq-arm64.h
++++ b/tools/testing/selftests/rseq/rseq-arm64.h
+@@ -230,8 +230,8 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "Qo" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -287,8 +287,8 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "Qo" (*v),
+ [expectnot] "r" (expectnot),
+ [load] "Qo" (*load),
+@@ -337,8 +337,8 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "Qo" (*v),
+ [count] "r" (count)
+ RSEQ_INJECT_INPUT
+@@ -388,8 +388,8 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [expect] "r" (expect),
+ [v] "Qo" (*v),
+ [newv] "r" (newv),
+@@ -447,8 +447,8 @@ int rseq_cmpeqv_trystorev_storev_release
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [expect] "r" (expect),
+ [v] "Qo" (*v),
+ [newv] "r" (newv),
+@@ -508,8 +508,8 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "Qo" (*v),
+ [expect] "r" (expect),
+ [v2] "Qo" (*v2),
+@@ -569,8 +569,8 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [expect] "r" (expect),
+ [v] "Qo" (*v),
+ [newv] "r" (newv),
+@@ -629,8 +629,8 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [expect] "r" (expect),
+ [v] "Qo" (*v),
+ [newv] "r" (newv),
+--- a/tools/testing/selftests/rseq/rseq-mips.h
++++ b/tools/testing/selftests/rseq/rseq-mips.h
+@@ -190,8 +190,8 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -258,8 +258,8 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -319,8 +319,8 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "m" (*v),
+ [count] "Ir" (count)
+ RSEQ_INJECT_INPUT
+@@ -382,8 +382,8 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -456,8 +456,8 @@ int rseq_cmpeqv_trystorev_storev_release
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -532,8 +532,8 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ "5:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -649,8 +649,8 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ "8:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+@@ -771,8 +771,8 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ "8:\n\t"
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+--- a/tools/testing/selftests/rseq/rseq-ppc.h
++++ b/tools/testing/selftests/rseq/rseq-ppc.h
+@@ -235,8 +235,8 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -301,8 +301,8 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -359,8 +359,8 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "r" (count)
+@@ -419,8 +419,8 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -489,8 +489,8 @@ int rseq_cmpeqv_trystorev_storev_release
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -560,8 +560,8 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -635,8 +635,8 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+@@ -711,8 +711,8 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+--- a/tools/testing/selftests/rseq/rseq-s390.h
++++ b/tools/testing/selftests/rseq/rseq-s390.h
+@@ -165,8 +165,8 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -233,8 +233,8 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -288,8 +288,8 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "r" (count)
+@@ -347,8 +347,8 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -426,8 +426,8 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -534,8 +534,8 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ #endif
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [current_cpu_id] "m" (__rseq_abi.cpu_id),
+- [rseq_cs] "m" (__rseq_abi.rseq_cs),
++ [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
++ [rseq_cs] "m" (rseq_get_abi()->rseq_cs),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+--- a/tools/testing/selftests/rseq/rseq-x86.h
++++ b/tools/testing/selftests/rseq/rseq-x86.h
+@@ -141,7 +141,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -207,7 +207,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -258,7 +258,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "er" (count)
+@@ -314,7 +314,7 @@ int rseq_offset_deref_addv(intptr_t *ptr
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* final store input */
+ [ptr] "m" (*ptr),
+ [off] "er" (off),
+@@ -372,7 +372,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -449,7 +449,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -555,7 +555,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ #endif
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
+@@ -719,7 +719,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -785,7 +785,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -836,7 +836,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "ir" (count)
+@@ -894,7 +894,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "m" (newv2),
+@@ -962,7 +962,7 @@ int rseq_cmpeqv_trystorev_storev_release
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -1032,7 +1032,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -1142,7 +1142,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ #endif
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "m" (expect),
+@@ -1255,7 +1255,7 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ #endif
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (&__rseq_abi),
++ [rseq_abi] "r" (rseq_get_abi()),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "m" (expect),
+--- a/tools/testing/selftests/rseq/rseq.h
++++ b/tools/testing/selftests/rseq/rseq.h
+@@ -46,6 +46,11 @@
+ extern __thread struct rseq_abi __rseq_abi;
+ extern int __rseq_handled;
+
++static inline struct rseq_abi *rseq_get_abi(void)
++{
++ return &__rseq_abi;
++}
++
+ #define rseq_likely(x) __builtin_expect(!!(x), 1)
+ #define rseq_unlikely(x) __builtin_expect(!!(x), 0)
+ #define rseq_barrier() __asm__ __volatile__("" : : : "memory")
+@@ -108,7 +113,7 @@ int32_t rseq_fallback_current_cpu(void);
+ */
+ static inline int32_t rseq_current_cpu_raw(void)
+ {
+- return RSEQ_ACCESS_ONCE(__rseq_abi.cpu_id);
++ return RSEQ_ACCESS_ONCE(rseq_get_abi()->cpu_id);
+ }
+
+ /*
+@@ -124,7 +129,7 @@ static inline int32_t rseq_current_cpu_r
+ */
+ static inline uint32_t rseq_cpu_start(void)
+ {
+- return RSEQ_ACCESS_ONCE(__rseq_abi.cpu_id_start);
++ return RSEQ_ACCESS_ONCE(rseq_get_abi()->cpu_id_start);
+ }
+
+ static inline uint32_t rseq_current_cpu(void)
+@@ -139,7 +144,7 @@ static inline uint32_t rseq_current_cpu(
+
+ static inline void rseq_clear_rseq_cs(void)
+ {
+- RSEQ_WRITE_ONCE(__rseq_abi.rseq_cs.arch.ptr, 0);
++ RSEQ_WRITE_ONCE(rseq_get_abi()->rseq_cs.arch.ptr, 0);
+ }
+
+ /*
--- /dev/null
+From 886ddfba933f5ce9d76c278165d834d114ba4ffc Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:44 -0500
+Subject: selftests/rseq: Introduce thread pointer getters
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 886ddfba933f5ce9d76c278165d834d114ba4ffc upstream.
+
+This is done in preparation for the selftest uplift to become compatible
+with glibc-2.35.
+
+glibc-2.35 exposes the rseq per-thread data in the TCB, accessible
+at an offset from the thread pointer.
+
+The toolchains do not implement accessing the thread pointer on all
+architectures. Provide thread pointer getters for ppc and x86 which
+lack (or lacked until recently) toolchain support.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-7-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-generic-thread-pointer.h | 25 ++++++++
+ tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h | 30 +++++++++
+ tools/testing/selftests/rseq/rseq-thread-pointer.h | 19 ++++++
+ tools/testing/selftests/rseq/rseq-x86-thread-pointer.h | 40 +++++++++++++
+ 4 files changed, 114 insertions(+)
+ create mode 100644 tools/testing/selftests/rseq/rseq-generic-thread-pointer.h
+ create mode 100644 tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h
+ create mode 100644 tools/testing/selftests/rseq/rseq-thread-pointer.h
+ create mode 100644 tools/testing/selftests/rseq/rseq-x86-thread-pointer.h
+
+--- /dev/null
++++ b/tools/testing/selftests/rseq/rseq-generic-thread-pointer.h
+@@ -0,0 +1,25 @@
++/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */
++/*
++ * rseq-generic-thread-pointer.h
++ *
++ * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ */
++
++#ifndef _RSEQ_GENERIC_THREAD_POINTER
++#define _RSEQ_GENERIC_THREAD_POINTER
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* Use gcc builtin thread pointer. */
++static inline void *rseq_thread_pointer(void)
++{
++ return __builtin_thread_pointer();
++}
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+--- /dev/null
++++ b/tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h
+@@ -0,0 +1,30 @@
++/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */
++/*
++ * rseq-ppc-thread-pointer.h
++ *
++ * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ */
++
++#ifndef _RSEQ_PPC_THREAD_POINTER
++#define _RSEQ_PPC_THREAD_POINTER
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++static inline void *rseq_thread_pointer(void)
++{
++#ifdef __powerpc64__
++ register void *__result asm ("r13");
++#else
++ register void *__result asm ("r2");
++#endif
++ asm ("" : "=r" (__result));
++ return __result;
++}
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+--- /dev/null
++++ b/tools/testing/selftests/rseq/rseq-thread-pointer.h
+@@ -0,0 +1,19 @@
++/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */
++/*
++ * rseq-thread-pointer.h
++ *
++ * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ */
++
++#ifndef _RSEQ_THREAD_POINTER
++#define _RSEQ_THREAD_POINTER
++
++#if defined(__x86_64__) || defined(__i386__)
++#include "rseq-x86-thread-pointer.h"
++#elif defined(__PPC__)
++#include "rseq-ppc-thread-pointer.h"
++#else
++#include "rseq-generic-thread-pointer.h"
++#endif
++
++#endif
+--- /dev/null
++++ b/tools/testing/selftests/rseq/rseq-x86-thread-pointer.h
+@@ -0,0 +1,40 @@
++/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */
++/*
++ * rseq-x86-thread-pointer.h
++ *
++ * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ */
++
++#ifndef _RSEQ_X86_THREAD_POINTER
++#define _RSEQ_X86_THREAD_POINTER
++
++#include <features.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#if __GNUC_PREREQ (11, 1)
++static inline void *rseq_thread_pointer(void)
++{
++ return __builtin_thread_pointer();
++}
++#else
++static inline void *rseq_thread_pointer(void)
++{
++ void *__result;
++
++# ifdef __x86_64__
++ __asm__ ("mov %%fs:0, %0" : "=r" (__result));
++# else
++ __asm__ ("mov %%gs:0, %0" : "=r" (__result));
++# endif
++ return __result;
++}
++#endif /* !GCC 11 */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
--- /dev/null
+From 94c5cf2a0e193afffef8de48ddc42de6df7cac93 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:50 -0500
+Subject: selftests/rseq: Remove arm/mips asm goto compiler work-around
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 94c5cf2a0e193afffef8de48ddc42de6df7cac93 upstream.
+
+The arm and mips work-around for asm goto size guess issues are not
+properly documented, and lack reference to specific compiler versions,
+upstream compiler bug tracker entry, and reproducer.
+
+I can only find a loosely documented patch in my original LKML rseq post
+refering to gcc < 7 on ARM, but it does not appear to be sufficient to
+track the exact issue. Also, I am not sure MIPS really has the same
+limitation.
+
+Therefore, remove the work-around until we can properly document this.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/lkml/20171121141900.18471-17-mathieu.desnoyers@efficios.com/
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-arm.h | 37 -------------------------------
+ tools/testing/selftests/rseq/rseq-mips.h | 37 -------------------------------
+ 2 files changed, 74 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq-arm.h
++++ b/tools/testing/selftests/rseq/rseq-arm.h
+@@ -147,14 +147,11 @@ do { \
+ teardown \
+ "b %l[" __rseq_str(cmpfail_label) "]\n\t"
+
+-#define rseq_workaround_gcc_asm_size_guess() __asm__ __volatile__("")
+-
+ static inline __attribute__((always_inline))
+ int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -198,14 +195,11 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -221,7 +215,6 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -270,14 +263,11 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -292,7 +282,6 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ #ifdef RSEQ_COMPARE_TWICE
+@@ -328,10 +317,8 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ , error1
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ #ifdef RSEQ_COMPARE_TWICE
+@@ -347,7 +334,6 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -398,14 +384,11 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -422,7 +405,6 @@ int rseq_cmpeqv_trystorev_storev_release
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -474,14 +456,11 @@ int rseq_cmpeqv_trystorev_storev_release
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -498,7 +477,6 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -554,14 +532,11 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ , error1, error2, error3
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -582,7 +557,6 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -678,21 +652,16 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+- rseq_workaround_gcc_asm_size_guess();
+ rseq_bug("cpu_id comparison failed");
+ error2:
+- rseq_workaround_gcc_asm_size_guess();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -706,7 +675,6 @@ int rseq_cmpeqv_trymemcpy_storev_release
+
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -803,21 +771,16 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+- rseq_workaround_gcc_asm_size_guess();
+ rseq_bug("cpu_id comparison failed");
+ error2:
+- rseq_workaround_gcc_asm_size_guess();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+--- a/tools/testing/selftests/rseq/rseq-mips.h
++++ b/tools/testing/selftests/rseq/rseq-mips.h
+@@ -154,14 +154,11 @@ do { \
+ teardown \
+ "b %l[" __rseq_str(cmpfail_label) "]\n\t"
+
+-#define rseq_workaround_gcc_asm_size_guess() __asm__ __volatile__("")
+-
+ static inline __attribute__((always_inline))
+ int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -203,14 +200,11 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -226,7 +220,6 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -273,14 +266,11 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -295,7 +285,6 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ #ifdef RSEQ_COMPARE_TWICE
+@@ -331,10 +320,8 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ , error1
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ #ifdef RSEQ_COMPARE_TWICE
+@@ -350,7 +337,6 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -399,14 +385,11 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -423,7 +406,6 @@ int rseq_cmpeqv_trystorev_storev_release
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -473,14 +455,11 @@ int rseq_cmpeqv_trystorev_storev_release
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -497,7 +476,6 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ {
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -549,14 +527,11 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ , error1, error2, error3
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+@@ -577,7 +552,6 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -670,21 +644,16 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+- rseq_workaround_gcc_asm_size_guess();
+ rseq_bug("cpu_id comparison failed");
+ error2:
+- rseq_workaround_gcc_asm_size_guess();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
+@@ -698,7 +667,6 @@ int rseq_cmpeqv_trymemcpy_storev_release
+
+ RSEQ_INJECT_C(9)
+
+- rseq_workaround_gcc_asm_size_guess();
+ __asm__ __volatile__ goto (
+ RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+@@ -792,21 +760,16 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ , error1, error2
+ #endif
+ );
+- rseq_workaround_gcc_asm_size_guess();
+ return 0;
+ abort:
+- rseq_workaround_gcc_asm_size_guess();
+ RSEQ_INJECT_FAILED
+ return -1;
+ cmpfail:
+- rseq_workaround_gcc_asm_size_guess();
+ return 1;
+ #ifdef RSEQ_COMPARE_TWICE
+ error1:
+- rseq_workaround_gcc_asm_size_guess();
+ rseq_bug("cpu_id comparison failed");
+ error2:
+- rseq_workaround_gcc_asm_size_guess();
+ rseq_bug("expected value comparison failed");
+ #endif
+ }
--- /dev/null
+From 07ad4f7629d4802ff0d962b0ac23ea6445964e2a Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Thu, 9 Dec 2021 16:19:09 -0700
+Subject: selftests/rseq: remove ARRAY_SIZE define from individual tests
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 07ad4f7629d4802ff0d962b0ac23ea6445964e2a upstream.
+
+ARRAY_SIZE is defined in several selftests. Remove definitions from
+individual test files and include header file for the define instead.
+ARRAY_SIZE define is added in a separate patch to prepare for this
+change.
+
+Remove ARRAY_SIZE from rseq tests and pickup the one defined in
+kselftest.h.
+
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/basic_percpu_ops_test.c | 3 +--
+ tools/testing/selftests/rseq/rseq.c | 3 +--
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+--- a/tools/testing/selftests/rseq/basic_percpu_ops_test.c
++++ b/tools/testing/selftests/rseq/basic_percpu_ops_test.c
+@@ -9,10 +9,9 @@
+ #include <string.h>
+ #include <stddef.h>
+
++#include "../kselftest.h"
+ #include "rseq.h"
+
+-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+-
+ struct percpu_lock_entry {
+ intptr_t v;
+ } __attribute__((aligned(128)));
+--- a/tools/testing/selftests/rseq/rseq.c
++++ b/tools/testing/selftests/rseq/rseq.c
+@@ -27,10 +27,9 @@
+ #include <signal.h>
+ #include <limits.h>
+
++#include "../kselftest.h"
+ #include "rseq.h"
+
+-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+-
+ __thread volatile struct rseq __rseq_abi = {
+ .cpu_id = RSEQ_CPU_ID_UNINITIALIZED,
+ };
--- /dev/null
+From 930378d056eac2c96407b02aafe4938d0ac9cc37 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:41 -0500
+Subject: selftests/rseq: Remove useless assignment to cpu variable
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 930378d056eac2c96407b02aafe4938d0ac9cc37 upstream.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-4-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/param_test.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/tools/testing/selftests/rseq/param_test.c
++++ b/tools/testing/selftests/rseq/param_test.c
+@@ -368,9 +368,7 @@ void *test_percpu_spinlock_thread(void *
+ abort();
+ reps = thread_data->reps;
+ for (i = 0; i < reps; i++) {
+- int cpu = rseq_cpu_start();
+-
+- cpu = rseq_this_cpu_lock(&data->lock);
++ int cpu = rseq_this_cpu_lock(&data->lock);
+ data->c[cpu].count++;
+ rseq_percpu_unlock(&data->lock, cpu);
+ #ifndef BENCHMARK
--- /dev/null
+From 94b80a19ebfe347a01301d750040a61c38200e2b Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:42 -0500
+Subject: selftests/rseq: Remove volatile from __rseq_abi
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 94b80a19ebfe347a01301d750040a61c38200e2b upstream.
+
+This is done in preparation for the selftest uplift to become compatible
+with glibc-2.35.
+
+All accesses to the __rseq_abi fields are volatile, but remove the
+volatile from the TLS variable declaration, otherwise we are stuck with
+volatile for the upcoming rseq_get_abi() helper.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-5-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq.c | 4 ++--
+ tools/testing/selftests/rseq/rseq.h | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq.c
++++ b/tools/testing/selftests/rseq/rseq.c
+@@ -30,7 +30,7 @@
+ #include "../kselftest.h"
+ #include "rseq.h"
+
+-__thread volatile struct rseq_abi __rseq_abi = {
++__thread struct rseq_abi __rseq_abi = {
+ .cpu_id = RSEQ_ABI_CPU_ID_UNINITIALIZED,
+ };
+
+@@ -92,7 +92,7 @@ int rseq_register_current_thread(void)
+ goto end;
+ }
+ if (errno != EBUSY)
+- __rseq_abi.cpu_id = RSEQ_ABI_CPU_ID_REGISTRATION_FAILED;
++ RSEQ_WRITE_ONCE(__rseq_abi.cpu_id, RSEQ_ABI_CPU_ID_REGISTRATION_FAILED);
+ ret = -1;
+ __rseq_refcount--;
+ end:
+--- a/tools/testing/selftests/rseq/rseq.h
++++ b/tools/testing/selftests/rseq/rseq.h
+@@ -43,7 +43,7 @@
+ #define RSEQ_INJECT_FAILED
+ #endif
+
+-extern __thread volatile struct rseq_abi __rseq_abi;
++extern __thread struct rseq_abi __rseq_abi;
+ extern int __rseq_handled;
+
+ #define rseq_likely(x) __builtin_expect(!!(x), 1)
+@@ -139,7 +139,7 @@ static inline uint32_t rseq_current_cpu(
+
+ static inline void rseq_clear_rseq_cs(void)
+ {
+- __rseq_abi.rseq_cs.arch.ptr = 0;
++ RSEQ_WRITE_ONCE(__rseq_abi.rseq_cs.arch.ptr, 0);
+ }
+
+ /*
--- /dev/null
+From 233e667e1ae3e348686bd9dd0172e62a09d852e1 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:45 -0500
+Subject: selftests/rseq: Uplift rseq selftests for compatibility with glibc-2.35
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 233e667e1ae3e348686bd9dd0172e62a09d852e1 upstream.
+
+glibc-2.35 (upcoming release date 2022-02-01) exposes the rseq per-thread
+data in the TCB, accessible at an offset from the thread pointer, rather
+than through an actual Thread-Local Storage (TLS) variable, as the
+Linux kernel selftests initially expected.
+
+The __rseq_abi TLS and glibc-2.35's ABI for per-thread data cannot
+actively coexist in a process, because the kernel supports only a single
+rseq registration per thread.
+
+Here is the scheme introduced to ensure selftests can work both with an
+older glibc and with glibc-2.35+:
+
+- librseq exposes its own "rseq_offset, rseq_size, rseq_flags" ABI.
+
+- librseq queries for glibc rseq ABI (__rseq_offset, __rseq_size,
+ __rseq_flags) using dlsym() in a librseq library constructor. If those
+ are found, copy their values into rseq_offset, rseq_size, and
+ rseq_flags.
+
+- Else, if those glibc symbols are not found, handle rseq registration
+ from librseq and use its own IE-model TLS to implement the rseq ABI
+ per-thread storage.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-8-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/Makefile | 2
+ tools/testing/selftests/rseq/rseq.c | 161 ++++++++++++++++------------------
+ tools/testing/selftests/rseq/rseq.h | 13 ++
+ 3 files changed, 88 insertions(+), 88 deletions(-)
+
+--- a/tools/testing/selftests/rseq/Makefile
++++ b/tools/testing/selftests/rseq/Makefile
+@@ -6,7 +6,7 @@ endif
+
+ CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L$(OUTPUT) -Wl,-rpath=./ \
+ $(CLANG_FLAGS)
+-LDLIBS += -lpthread
++LDLIBS += -lpthread -ldl
+
+ # Own dependencies because we only want to build against 1st prerequisite, but
+ # still track changes to header files and depend on shared object.
+--- a/tools/testing/selftests/rseq/rseq.c
++++ b/tools/testing/selftests/rseq/rseq.c
+@@ -26,103 +26,113 @@
+ #include <assert.h>
+ #include <signal.h>
+ #include <limits.h>
++#include <dlfcn.h>
+
+ #include "../kselftest.h"
+ #include "rseq.h"
+
+-__thread struct rseq_abi __rseq_abi = {
+- .cpu_id = RSEQ_ABI_CPU_ID_UNINITIALIZED,
+-};
++static const int *libc_rseq_offset_p;
++static const unsigned int *libc_rseq_size_p;
++static const unsigned int *libc_rseq_flags_p;
++
++/* Offset from the thread pointer to the rseq area. */
++int rseq_offset;
++
++/* Size of the registered rseq area. 0 if the registration was
++ unsuccessful. */
++unsigned int rseq_size = -1U;
+
+-/*
+- * Shared with other libraries. This library may take rseq ownership if it is
+- * still 0 when executing the library constructor. Set to 1 by library
+- * constructor when handling rseq. Set to 0 in destructor if handling rseq.
+- */
+-int __rseq_handled;
++/* Flags used during rseq registration. */
++unsigned int rseq_flags;
+
+-/* Whether this library have ownership of rseq registration. */
+ static int rseq_ownership;
+
+-static __thread volatile uint32_t __rseq_refcount;
++static
++__thread struct rseq_abi __rseq_abi __attribute__((tls_model("initial-exec"))) = {
++ .cpu_id = RSEQ_ABI_CPU_ID_UNINITIALIZED,
++};
+
+-static void signal_off_save(sigset_t *oldset)
++static int sys_rseq(struct rseq_abi *rseq_abi, uint32_t rseq_len,
++ int flags, uint32_t sig)
+ {
+- sigset_t set;
+- int ret;
+-
+- sigfillset(&set);
+- ret = pthread_sigmask(SIG_BLOCK, &set, oldset);
+- if (ret)
+- abort();
++ return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig);
+ }
+
+-static void signal_restore(sigset_t oldset)
++int rseq_available(void)
+ {
+- int ret;
++ int rc;
+
+- ret = pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+- if (ret)
++ rc = sys_rseq(NULL, 0, 0, 0);
++ if (rc != -1)
+ abort();
+-}
+-
+-static int sys_rseq(volatile struct rseq_abi *rseq_abi, uint32_t rseq_len,
+- int flags, uint32_t sig)
+-{
+- return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig);
++ switch (errno) {
++ case ENOSYS:
++ return 0;
++ case EINVAL:
++ return 1;
++ default:
++ abort();
++ }
+ }
+
+ int rseq_register_current_thread(void)
+ {
+- int rc, ret = 0;
+- sigset_t oldset;
++ int rc;
+
+- if (!rseq_ownership)
++ if (!rseq_ownership) {
++ /* Treat libc's ownership as a successful registration. */
+ return 0;
+- signal_off_save(&oldset);
+- if (__rseq_refcount == UINT_MAX) {
+- ret = -1;
+- goto end;
+ }
+- if (__rseq_refcount++)
+- goto end;
+ rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), 0, RSEQ_SIG);
+- if (!rc) {
+- assert(rseq_current_cpu_raw() >= 0);
+- goto end;
+- }
+- if (errno != EBUSY)
+- RSEQ_WRITE_ONCE(__rseq_abi.cpu_id, RSEQ_ABI_CPU_ID_REGISTRATION_FAILED);
+- ret = -1;
+- __rseq_refcount--;
+-end:
+- signal_restore(oldset);
+- return ret;
++ if (rc)
++ return -1;
++ assert(rseq_current_cpu_raw() >= 0);
++ return 0;
+ }
+
+ int rseq_unregister_current_thread(void)
+ {
+- int rc, ret = 0;
+- sigset_t oldset;
++ int rc;
+
+- if (!rseq_ownership)
++ if (!rseq_ownership) {
++ /* Treat libc's ownership as a successful unregistration. */
+ return 0;
+- signal_off_save(&oldset);
+- if (!__rseq_refcount) {
+- ret = -1;
+- goto end;
+ }
+- if (--__rseq_refcount)
+- goto end;
+- rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi),
+- RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG);
+- if (!rc)
+- goto end;
+- __rseq_refcount = 1;
+- ret = -1;
+-end:
+- signal_restore(oldset);
+- return ret;
++ rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG);
++ if (rc)
++ return -1;
++ return 0;
++}
++
++static __attribute__((constructor))
++void rseq_init(void)
++{
++ libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
++ libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
++ libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");
++ if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p) {
++ /* rseq registration owned by glibc */
++ rseq_offset = *libc_rseq_offset_p;
++ rseq_size = *libc_rseq_size_p;
++ rseq_flags = *libc_rseq_flags_p;
++ return;
++ }
++ if (!rseq_available())
++ return;
++ rseq_ownership = 1;
++ rseq_offset = (void *)&__rseq_abi - rseq_thread_pointer();
++ rseq_size = sizeof(struct rseq_abi);
++ rseq_flags = 0;
++}
++
++static __attribute__((destructor))
++void rseq_exit(void)
++{
++ if (!rseq_ownership)
++ return;
++ rseq_offset = 0;
++ rseq_size = -1U;
++ rseq_ownership = 0;
+ }
+
+ int32_t rseq_fallback_current_cpu(void)
+@@ -136,20 +146,3 @@ int32_t rseq_fallback_current_cpu(void)
+ }
+ return cpu;
+ }
+-
+-void __attribute__((constructor)) rseq_init(void)
+-{
+- /* Check whether rseq is handled by another library. */
+- if (__rseq_handled)
+- return;
+- __rseq_handled = 1;
+- rseq_ownership = 1;
+-}
+-
+-void __attribute__((destructor)) rseq_fini(void)
+-{
+- if (!rseq_ownership)
+- return;
+- __rseq_handled = 0;
+- rseq_ownership = 0;
+-}
+--- a/tools/testing/selftests/rseq/rseq.h
++++ b/tools/testing/selftests/rseq/rseq.h
+@@ -43,12 +43,19 @@
+ #define RSEQ_INJECT_FAILED
+ #endif
+
+-extern __thread struct rseq_abi __rseq_abi;
+-extern int __rseq_handled;
++#include "rseq-thread-pointer.h"
++
++/* Offset from the thread pointer to the rseq area. */
++extern int rseq_offset;
++/* Size of the registered rseq area. 0 if the registration was
++ unsuccessful. */
++extern unsigned int rseq_size;
++/* Flags used during rseq registration. */
++extern unsigned int rseq_flags;
+
+ static inline struct rseq_abi *rseq_get_abi(void)
+ {
+- return &__rseq_abi;
++ return (struct rseq_abi *) ((uintptr_t) rseq_thread_pointer() + rseq_offset);
+ }
+
+ #define rseq_likely(x) __builtin_expect(!!(x), 1)
--- /dev/null
+From 127b6429d235ab7c358223bbfd8a8b8d8cc799b6 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:53 -0500
+Subject: selftests/rseq: x86-32: use %gs segment selector for accessing rseq thread area
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 127b6429d235ab7c358223bbfd8a8b8d8cc799b6 upstream.
+
+Rather than use rseq_get_abi() and pass its result through a register to
+the inline assembler, directly access the per-thread rseq area through a
+memory reference combining the %gs segment selector, the constant offset
+of the field in struct rseq, and the rseq_offset value (in a register).
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-16-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-x86.h | 66 ++++++++++++++++----------------
+ 1 file changed, 34 insertions(+), 32 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq-x86.h
++++ b/tools/testing/selftests/rseq/rseq-x86.h
+@@ -633,6 +633,8 @@ int rseq_cmpeqv_trymemcpy_storev_release
+
+ #elif defined(__i386__)
+
++#define RSEQ_ASM_TP_SEGMENT %%gs
++
+ #define rseq_smp_mb() \
+ __asm__ __volatile__ ("lock; addl $0,-128(%%esp)" ::: "memory", "cc")
+ #define rseq_smp_rmb() \
+@@ -732,14 +734,14 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "cmpl %[v], %[expect]\n\t"
+ "jnz %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "cmpl %[v], %[expect]\n\t"
+ "jnz %l[error2]\n\t"
+ #endif
+@@ -750,7 +752,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" (rseq_offset),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -798,15 +800,15 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "movl %[v], %%ebx\n\t"
+ "cmpl %%ebx, %[expectnot]\n\t"
+ "je %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "movl %[v], %%ebx\n\t"
+ "cmpl %%ebx, %[expectnot]\n\t"
+ "je %l[error2]\n\t"
+@@ -821,7 +823,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" (rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -864,11 +866,11 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ #endif
+ /* final store */
+ "addl %[count], %[v]\n\t"
+@@ -877,7 +879,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" (rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "ir" (count)
+@@ -916,14 +918,14 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "cmpl %[v], %[expect]\n\t"
+ "jnz %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "cmpl %[v], %[expect]\n\t"
+ "jnz %l[error2]\n\t"
+ #endif
+@@ -938,7 +940,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" (rseq_offset),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "m" (newv2),
+@@ -987,15 +989,15 @@ int rseq_cmpeqv_trystorev_storev_release
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "movl %[expect], %%eax\n\t"
+ "cmpl %[v], %%eax\n\t"
+ "jnz %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "movl %[expect], %%eax\n\t"
+ "cmpl %[v], %%eax\n\t"
+ "jnz %l[error2]\n\t"
+@@ -1011,7 +1013,7 @@ int rseq_cmpeqv_trystorev_storev_release
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" (rseq_offset),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -1062,8 +1064,8 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error3])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "cmpl %[v], %[expect]\n\t"
+ "jnz %l[cmpfail]\n\t"
+@@ -1072,7 +1074,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ "jnz %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(5)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "cmpl %[v], %[expect]\n\t"
+ "jnz %l[error2]\n\t"
+ "cmpl %[expect2], %[v2]\n\t"
+@@ -1086,7 +1088,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" (rseq_offset),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -1144,15 +1146,15 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ "movl %[dst], %[rseq_scratch1]\n\t"
+ "movl %[len], %[rseq_scratch2]\n\t"
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "movl %[expect], %%eax\n\t"
+ "cmpl %%eax, %[v]\n\t"
+ "jnz 5f\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 6f)
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 6f)
+ "movl %[expect], %%eax\n\t"
+ "cmpl %%eax, %[v]\n\t"
+ "jnz 7f\n\t"
+@@ -1202,7 +1204,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ #endif
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" (rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "m" (expect),
+@@ -1261,15 +1263,15 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ "movl %[dst], %[rseq_scratch1]\n\t"
+ "movl %[len], %[rseq_scratch2]\n\t"
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "movl %[expect], %%eax\n\t"
+ "cmpl %%eax, %[v]\n\t"
+ "jnz 5f\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 6f)
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 6f)
+ "movl %[expect], %%eax\n\t"
+ "cmpl %%eax, %[v]\n\t"
+ "jnz 7f\n\t"
+@@ -1320,7 +1322,7 @@ int rseq_cmpeqv_trymemcpy_storev_release
+ #endif
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" (rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "m" (expect),
--- /dev/null
+From 4e15bb766b6c6e963a4d33629034d0ec3b7637df Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 24 Jan 2022 12:12:52 -0500
+Subject: selftests/rseq: x86-64: use %fs segment selector for accessing rseq thread area
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 4e15bb766b6c6e963a4d33629034d0ec3b7637df upstream.
+
+Rather than use rseq_get_abi() and pass its result through a register to
+the inline assembler, directly access the per-thread rseq area through a
+memory reference combining the %fs segment selector, the constant offset
+of the field in struct rseq, and the rseq_offset value (in a register).
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20220124171253.22072-15-mathieu.desnoyers@efficios.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-x86.h | 58 ++++++++++++++++----------------
+ 1 file changed, 30 insertions(+), 28 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq-x86.h
++++ b/tools/testing/selftests/rseq/rseq-x86.h
+@@ -28,6 +28,8 @@
+
+ #ifdef __x86_64__
+
++#define RSEQ_ASM_TP_SEGMENT %%fs
++
+ #define rseq_smp_mb() \
+ __asm__ __volatile__ ("lock; addl $0,-128(%%rsp)" ::: "memory", "cc")
+ #define rseq_smp_rmb() rseq_barrier()
+@@ -123,14 +125,14 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "cmpq %[v], %[expect]\n\t"
+ "jnz %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "cmpq %[v], %[expect]\n\t"
+ "jnz %l[error2]\n\t"
+ #endif
+@@ -141,7 +143,7 @@ int rseq_cmpeqv_storev(intptr_t *v, intp
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" ((long)rseq_offset),
+ [v] "m" (*v),
+ [expect] "r" (expect),
+ [newv] "r" (newv)
+@@ -189,15 +191,15 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "movq %[v], %%rbx\n\t"
+ "cmpq %%rbx, %[expectnot]\n\t"
+ "je %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "movq %[v], %%rbx\n\t"
+ "cmpq %%rbx, %[expectnot]\n\t"
+ "je %l[error2]\n\t"
+@@ -212,7 +214,7 @@ int rseq_cmpnev_storeoffp_load(intptr_t
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" ((long)rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [expectnot] "r" (expectnot),
+@@ -255,11 +257,11 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ #endif
+ /* final store */
+ "addq %[count], %[v]\n\t"
+@@ -268,7 +270,7 @@ int rseq_addv(intptr_t *v, intptr_t coun
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" ((long)rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "er" (count)
+@@ -309,11 +311,11 @@ int rseq_offset_deref_addv(intptr_t *ptr
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ #endif
+ /* get p+v */
+ "movq %[ptr], %%rbx\n\t"
+@@ -327,7 +329,7 @@ int rseq_offset_deref_addv(intptr_t *ptr
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" ((long)rseq_offset),
+ /* final store input */
+ [ptr] "m" (*ptr),
+ [off] "er" (off),
+@@ -364,14 +366,14 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "cmpq %[v], %[expect]\n\t"
+ "jnz %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "cmpq %[v], %[expect]\n\t"
+ "jnz %l[error2]\n\t"
+ #endif
+@@ -385,7 +387,7 @@ int rseq_cmpeqv_trystorev_storev(intptr_
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" ((long)rseq_offset),
+ /* try store input */
+ [v2] "m" (*v2),
+ [newv2] "r" (newv2),
+@@ -444,8 +446,8 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error3])
+ #endif
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "cmpq %[v], %[expect]\n\t"
+ "jnz %l[cmpfail]\n\t"
+@@ -454,7 +456,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ "jnz %l[cmpfail]\n\t"
+ RSEQ_INJECT_ASM(5)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1])
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), %l[error1])
+ "cmpq %[v], %[expect]\n\t"
+ "jnz %l[error2]\n\t"
+ "cmpq %[v2], %[expect2]\n\t"
+@@ -467,7 +469,7 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *
+ RSEQ_ASM_DEFINE_ABORT(4, "", abort)
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" ((long)rseq_offset),
+ /* cmp2 input */
+ [v2] "m" (*v2),
+ [expect2] "r" (expect2),
+@@ -524,14 +526,14 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ "movq %[dst], %[rseq_scratch1]\n\t"
+ "movq %[len], %[rseq_scratch2]\n\t"
+ /* Start rseq by storing table entry pointer into rseq_cs. */
+- RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_CS_OFFSET(%[rseq_abi]))
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 4f)
++ RSEQ_ASM_STORE_RSEQ_CS(1, 3b, RSEQ_ASM_TP_SEGMENT:RSEQ_CS_OFFSET(%[rseq_offset]))
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 4f)
+ RSEQ_INJECT_ASM(3)
+ "cmpq %[v], %[expect]\n\t"
+ "jnz 5f\n\t"
+ RSEQ_INJECT_ASM(4)
+ #ifdef RSEQ_COMPARE_TWICE
+- RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), 6f)
++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_ASM_TP_SEGMENT:RSEQ_CPU_ID_OFFSET(%[rseq_offset]), 6f)
+ "cmpq %[v], %[expect]\n\t"
+ "jnz 7f\n\t"
+ #endif
+@@ -579,7 +581,7 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_
+ #endif
+ : /* gcc asm goto does not allow outputs */
+ : [cpu_id] "r" (cpu),
+- [rseq_abi] "r" (rseq_get_abi()),
++ [rseq_offset] "r" ((long)rseq_offset),
+ /* final store input */
+ [v] "m" (*v),
+ [expect] "r" (expect),
maintainers-add-leah-as-xfs-maintainer-for-5.15.y.patch
tcp-add-a-missing-nf_reset_ct-in-3whs-handling.patch
selftests-bpf-add-test_verifier-support-to-fixup-kfunc-call-insns.patch
+selftests-rseq-remove-array_size-define-from-individual-tests.patch
+selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch
+selftests-rseq-remove-useless-assignment-to-cpu-variable.patch
+selftests-rseq-remove-volatile-from-__rseq_abi.patch
+selftests-rseq-introduce-rseq_get_abi-helper.patch
+selftests-rseq-introduce-thread-pointer-getters.patch
+selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch
+selftests-rseq-fix-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch
+selftests-rseq-fix-ppc32-missing-instruction-selection-u-and-x-for-load-store.patch
+selftests-rseq-fix-ppc32-offsets-by-using-long-rather-than-off_t.patch
+selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch
+selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch
+selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch
+selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch
+selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch
+selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch
net-fix-iff_tx_skb_no_linear-definition.patch
drm-i915-gem-add-missing-else.patch
drm-msm-gem-fix-error-return-on-fence-id-alloc-fail.patch