]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Jul 2022 06:04:47 +0000 (08:04 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Jul 2022 06:04:47 +0000 (08:04 +0200)
added patches:
selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.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-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch
selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch
selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch
selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch
selftests-rseq-introduce-rseq_get_abi-helper.patch
selftests-rseq-introduce-thread-pointer-getters.patch
selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch
selftests-rseq-remove-array_size-define-from-individual-tests.patch
selftests-rseq-remove-useless-assignment-to-cpu-variable.patch
selftests-rseq-remove-volatile-from-__rseq_abi.patch
selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch
selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch
selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch

17 files changed:
queue-5.15/selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-fix-ppc32-missing-instruction-selection-u-and-x-for-load-store.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-fix-ppc32-offsets-by-using-long-rather-than-off_t.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-fix-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-introduce-rseq_get_abi-helper.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-introduce-thread-pointer-getters.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-remove-array_size-define-from-individual-tests.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-remove-useless-assignment-to-cpu-variable.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-remove-volatile-from-__rseq_abi.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch [new file with mode: 0644]
queue-5.15/selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch b/queue-5.15/selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch
new file mode 100644 (file)
index 0000000..882210b
--- /dev/null
@@ -0,0 +1,130 @@
+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;
diff --git a/queue-5.15/selftests-rseq-fix-ppc32-missing-instruction-selection-u-and-x-for-load-store.patch b/queue-5.15/selftests-rseq-fix-ppc32-missing-instruction-selection-u-and-x-for-load-store.patch
new file mode 100644 (file)
index 0000000..7433516
--- /dev/null
@@ -0,0 +1,188 @@
+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 */
diff --git a/queue-5.15/selftests-rseq-fix-ppc32-offsets-by-using-long-rather-than-off_t.patch b/queue-5.15/selftests-rseq-fix-ppc32-offsets-by-using-long-rather-than-off_t.patch
new file mode 100644 (file)
index 0000000..8d307f6
--- /dev/null
@@ -0,0 +1,150 @@
+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)
diff --git a/queue-5.15/selftests-rseq-fix-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch b/queue-5.15/selftests-rseq-fix-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch
new file mode 100644 (file)
index 0000000..a1281bd
--- /dev/null
@@ -0,0 +1,378 @@
+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),
diff --git a/queue-5.15/selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch b/queue-5.15/selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch
new file mode 100644 (file)
index 0000000..b70342f
--- /dev/null
@@ -0,0 +1,40 @@
+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")
diff --git a/queue-5.15/selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch b/queue-5.15/selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch
new file mode 100644 (file)
index 0000000..7182b8b
--- /dev/null
@@ -0,0 +1,1051 @@
+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.
diff --git a/queue-5.15/selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch b/queue-5.15/selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch
new file mode 100644 (file)
index 0000000..8b10ad7
--- /dev/null
@@ -0,0 +1,268 @@
+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;
+ }
+ /*
diff --git a/queue-5.15/selftests-rseq-introduce-rseq_get_abi-helper.patch b/queue-5.15/selftests-rseq-introduce-rseq_get_abi-helper.patch
new file mode 100644 (file)
index 0000000..01d6b01
--- /dev/null
@@ -0,0 +1,645 @@
+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);
+ }
+ /*
diff --git a/queue-5.15/selftests-rseq-introduce-thread-pointer-getters.patch b/queue-5.15/selftests-rseq-introduce-thread-pointer-getters.patch
new file mode 100644 (file)
index 0000000..a419edf
--- /dev/null
@@ -0,0 +1,160 @@
+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
diff --git a/queue-5.15/selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch b/queue-5.15/selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch
new file mode 100644 (file)
index 0000000..0e5c834
--- /dev/null
@@ -0,0 +1,435 @@
+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
+ }
diff --git a/queue-5.15/selftests-rseq-remove-array_size-define-from-individual-tests.patch b/queue-5.15/selftests-rseq-remove-array_size-define-from-individual-tests.patch
new file mode 100644 (file)
index 0000000..1e15002
--- /dev/null
@@ -0,0 +1,52 @@
+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,
+ };
diff --git a/queue-5.15/selftests-rseq-remove-useless-assignment-to-cpu-variable.patch b/queue-5.15/selftests-rseq-remove-useless-assignment-to-cpu-variable.patch
new file mode 100644 (file)
index 0000000..e473b21
--- /dev/null
@@ -0,0 +1,30 @@
+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
diff --git a/queue-5.15/selftests-rseq-remove-volatile-from-__rseq_abi.patch b/queue-5.15/selftests-rseq-remove-volatile-from-__rseq_abi.patch
new file mode 100644 (file)
index 0000000..ba15e79
--- /dev/null
@@ -0,0 +1,65 @@
+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);
+ }
+ /*
diff --git a/queue-5.15/selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch b/queue-5.15/selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch
new file mode 100644 (file)
index 0000000..ca8cadc
--- /dev/null
@@ -0,0 +1,282 @@
+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)
diff --git a/queue-5.15/selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch b/queue-5.15/selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch
new file mode 100644 (file)
index 0000000..d07f050
--- /dev/null
@@ -0,0 +1,252 @@
+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),
diff --git a/queue-5.15/selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch b/queue-5.15/selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch
new file mode 100644 (file)
index 0000000..a325e4c
--- /dev/null
@@ -0,0 +1,219 @@
+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),
index 235aeb076c9c90051928f580f5db7d0623444a47..960caacdbd2a0524838687a638e2d8493e705f53 100644 (file)
@@ -59,6 +59,22 @@ net-tun-avoid-disabling-napi-twice.patch
 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