From 56d77fa254ac0041eef3ef181ec2530d9ee79711 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 5 Jul 2022 12:45:13 +0200 Subject: [PATCH] 5.4-stable patches added patches: rseq-selftests-x86_64-add-rseq_offset_deref_addv.patch 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 --- ...ts-x86_64-add-rseq_offset_deref_addv.patch | 91 ++ ...nge-type-of-rseq_offset-to-ptrdiff_t.patch | 130 ++ ...ion-selection-u-and-x-for-load-store.patch | 188 +++ ...sets-by-using-long-rather-than-off_t.patch | 150 +++ ...s-32-bit-field-pointer-on-big-endian.patch | 378 ++++++ ...-about-if-checks-of-undefined-tokens.patch | 40 + ...x-work-around-asm-goto-compiler-bugs.patch | 1051 +++++++++++++++++ ...troduce-own-copy-of-rseq-uapi-header.patch | 268 +++++ ...s-rseq-introduce-rseq_get_abi-helper.patch | 645 ++++++++++ ...seq-introduce-thread-pointer-getters.patch | 160 +++ ...m-mips-asm-goto-compiler-work-around.patch | 435 +++++++ ...ay_size-define-from-individual-tests.patch | 52 + ...e-useless-assignment-to-cpu-variable.patch | 30 + ...rseq-remove-volatile-from-__rseq_abi.patch | 65 + ...ts-for-compatibility-with-glibc-2.35.patch | 282 +++++ ...ector-for-accessing-rseq-thread-area.patch | 252 ++++ ...ector-for-accessing-rseq-thread-area.patch | 219 ++++ queue-5.4/series | 17 + 18 files changed, 4453 insertions(+) create mode 100644 queue-5.4/rseq-selftests-x86_64-add-rseq_offset_deref_addv.patch create mode 100644 queue-5.4/selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch create mode 100644 queue-5.4/selftests-rseq-fix-ppc32-missing-instruction-selection-u-and-x-for-load-store.patch create mode 100644 queue-5.4/selftests-rseq-fix-ppc32-offsets-by-using-long-rather-than-off_t.patch create mode 100644 queue-5.4/selftests-rseq-fix-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch create mode 100644 queue-5.4/selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch create mode 100644 queue-5.4/selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch create mode 100644 queue-5.4/selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch create mode 100644 queue-5.4/selftests-rseq-introduce-rseq_get_abi-helper.patch create mode 100644 queue-5.4/selftests-rseq-introduce-thread-pointer-getters.patch create mode 100644 queue-5.4/selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch create mode 100644 queue-5.4/selftests-rseq-remove-array_size-define-from-individual-tests.patch create mode 100644 queue-5.4/selftests-rseq-remove-useless-assignment-to-cpu-variable.patch create mode 100644 queue-5.4/selftests-rseq-remove-volatile-from-__rseq_abi.patch create mode 100644 queue-5.4/selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch create mode 100644 queue-5.4/selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch create mode 100644 queue-5.4/selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch diff --git a/queue-5.4/rseq-selftests-x86_64-add-rseq_offset_deref_addv.patch b/queue-5.4/rseq-selftests-x86_64-add-rseq_offset_deref_addv.patch new file mode 100644 index 00000000000..752bda0600f --- /dev/null +++ b/queue-5.4/rseq-selftests-x86_64-add-rseq_offset_deref_addv.patch @@ -0,0 +1,91 @@ +From ea366dd79c05fcd4cf5e225d2de8a3a7c293160c Mon Sep 17 00:00:00 2001 +From: Peter Oskolkov +Date: Wed, 23 Sep 2020 16:36:17 -0700 +Subject: rseq/selftests,x86_64: Add rseq_offset_deref_addv() + +From: Peter Oskolkov + +commit ea366dd79c05fcd4cf5e225d2de8a3a7c293160c upstream. + +This patch adds rseq_offset_deref_addv() function to +tools/testing/selftests/rseq/rseq-x86.h, to be used in a selftest in +the next patch in the patchset. + +Once an architecture adds support for this function they should define +"RSEQ_ARCH_HAS_OFFSET_DEREF_ADDV". + +Signed-off-by: Peter Oskolkov +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Mathieu Desnoyers +Link: https://lkml.kernel.org/r/20200923233618.2572849-2-posk@google.com +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/rseq/rseq-x86.h | 57 ++++++++++++++++++++++++++++++++ + 1 file changed, 57 insertions(+) + +--- a/tools/testing/selftests/rseq/rseq-x86.h ++++ b/tools/testing/selftests/rseq/rseq-x86.h +@@ -279,6 +279,63 @@ error1: + #endif + } + ++#define RSEQ_ARCH_HAS_OFFSET_DEREF_ADDV ++ ++/* ++ * pval = *(ptr+off) ++ * *pval += inc; ++ */ ++static inline __attribute__((always_inline)) ++int rseq_offset_deref_addv(intptr_t *ptr, off_t off, intptr_t inc, int cpu) ++{ ++ RSEQ_INJECT_C(9) ++ ++ __asm__ __volatile__ goto ( ++ RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */ ++#ifdef RSEQ_COMPARE_TWICE ++ 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_INJECT_ASM(3) ++#ifdef RSEQ_COMPARE_TWICE ++ RSEQ_ASM_CMP_CPU_ID(cpu_id, RSEQ_CPU_ID_OFFSET(%[rseq_abi]), %l[error1]) ++#endif ++ /* get p+v */ ++ "movq %[ptr], %%rbx\n\t" ++ "addq %[off], %%rbx\n\t" ++ /* get pv */ ++ "movq (%%rbx), %%rcx\n\t" ++ /* *pv += inc */ ++ "addq %[inc], (%%rcx)\n\t" ++ "2:\n\t" ++ RSEQ_INJECT_ASM(4) ++ RSEQ_ASM_DEFINE_ABORT(4, "", abort) ++ : /* gcc asm goto does not allow outputs */ ++ : [cpu_id] "r" (cpu), ++ [rseq_abi] "r" (&__rseq_abi), ++ /* final store input */ ++ [ptr] "m" (*ptr), ++ [off] "er" (off), ++ [inc] "er" (inc) ++ : "memory", "cc", "rax", "rbx", "rcx" ++ RSEQ_INJECT_CLOBBER ++ : abort ++#ifdef RSEQ_COMPARE_TWICE ++ , error1 ++#endif ++ ); ++ return 0; ++abort: ++ RSEQ_INJECT_FAILED ++ return -1; ++#ifdef RSEQ_COMPARE_TWICE ++error1: ++ rseq_bug("cpu_id comparison failed"); ++#endif ++} ++ + static inline __attribute__((always_inline)) + int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect, + intptr_t *v2, intptr_t newv2, diff --git a/queue-5.4/selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch b/queue-5.4/selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch new file mode 100644 index 00000000000..882210bfc63 --- /dev/null +++ b/queue-5.4/selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch @@ -0,0 +1,130 @@ +From 889c5d60fbcf332c8b6ab7054d45f2768914a375 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Thu, 3 Feb 2022 10:05:32 -0500 +Subject: selftests/rseq: Change type of rseq_offset to ptrdiff_t + +From: Mathieu Desnoyers + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://sourceware.org/pipermail/libc-alpha/2022-February/136024.html +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + #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 + #include + #include ++#include + #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.4/selftests-rseq-fix-ppc32-missing-instruction-selection-u-and-x-for-load-store.patch b/queue-5.4/selftests-rseq-fix-ppc32-missing-instruction-selection-u-and-x-for-load-store.patch new file mode 100644 index 00000000000..743351668aa --- /dev/null +++ b/queue-5.4/selftests-rseq-fix-ppc32-missing-instruction-selection-u-and-x-for-load-store.patch @@ -0,0 +1,188 @@ +From de6b52a21420a18dc8a36438d581efd1313d5fe3 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +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 + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-10-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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.4/selftests-rseq-fix-ppc32-offsets-by-using-long-rather-than-off_t.patch b/queue-5.4/selftests-rseq-fix-ppc32-offsets-by-using-long-rather-than-off_t.patch new file mode 100644 index 00000000000..86d7e05a69d --- /dev/null +++ b/queue-5.4/selftests-rseq-fix-ppc32-offsets-by-using-long-rather-than-off_t.patch @@ -0,0 +1,150 @@ +From 26dc8a6d8e11552f3b797b5aafe01071ca32d692 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +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 + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-11-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -547,7 +547,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.4/selftests-rseq-fix-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch b/queue-5.4/selftests-rseq-fix-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch new file mode 100644 index 00000000000..a1281bd2539 --- /dev/null +++ b/queue-5.4/selftests-rseq-fix-ppc32-wrong-rseq_cs-32-bit-field-pointer-on-big-endian.patch @@ -0,0 +1,378 @@ +From 24d1136a29da5953de5c0cbc6c83eb62a1e0bf14 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +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 + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-9-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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.4/selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch b/queue-5.4/selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch new file mode 100644 index 00000000000..8cca8a65725 --- /dev/null +++ b/queue-5.4/selftests-rseq-fix-warnings-about-if-checks-of-undefined-tokens.patch @@ -0,0 +1,40 @@ +From d7ed99ade3e62b755584eea07b4e499e79240527 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:49 -0500 +Subject: selftests/rseq: Fix warnings about #if checks of undefined tokens + +From: Mathieu Desnoyers + +commit d7ed99ade3e62b755584eea07b4e499e79240527 upstream. + +Signed-off-by: Mathieu Desnoyers +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-12-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -159,7 +159,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.4/selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch b/queue-5.4/selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch new file mode 100644 index 00000000000..7182b8b510a --- /dev/null +++ b/queue-5.4/selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch @@ -0,0 +1,1051 @@ +From b53823fb2ef854222853be164f3b1e815f315144 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:51 -0500 +Subject: selftests/rseq: Fix: work-around asm goto compiler bugs + +From: Mathieu Desnoyers + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-14-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++ */ ++ ++#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 + #include + #include "rseq-abi.h" ++#include "compiler.h" + + /* + * Empty code injection macros, override when testing. diff --git a/queue-5.4/selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch b/queue-5.4/selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch new file mode 100644 index 00000000000..8b10ad7ebff --- /dev/null +++ b/queue-5.4/selftests-rseq-introduce-own-copy-of-rseq-uapi-header.patch @@ -0,0 +1,268 @@ +From 5c105d55a9dc9e01535116ccfc26e703168a574f Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:39 -0500 +Subject: selftests/rseq: introduce own copy of rseq uapi header + +From: Mathieu Desnoyers + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-2-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++ */ ++ ++#include ++#include ++ ++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 + #include + #include +-#include ++#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.4/selftests-rseq-introduce-rseq_get_abi-helper.patch b/queue-5.4/selftests-rseq-introduce-rseq_get_abi-helper.patch new file mode 100644 index 00000000000..01d6b01ac78 --- /dev/null +++ b/queue-5.4/selftests-rseq-introduce-rseq_get_abi-helper.patch @@ -0,0 +1,645 @@ +From e546cd48ccc456074ddb8920732aef4af65d7ca7 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:43 -0500 +Subject: selftests/rseq: Introduce rseq_get_abi() helper + +From: Mathieu Desnoyers + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-6-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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.4/selftests-rseq-introduce-thread-pointer-getters.patch b/queue-5.4/selftests-rseq-introduce-thread-pointer-getters.patch new file mode 100644 index 00000000000..a419edf1d42 --- /dev/null +++ b/queue-5.4/selftests-rseq-introduce-thread-pointer-getters.patch @@ -0,0 +1,160 @@ +From 886ddfba933f5ce9d76c278165d834d114ba4ffc Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:44 -0500 +Subject: selftests/rseq: Introduce thread pointer getters + +From: Mathieu Desnoyers + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-7-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++ */ ++ ++#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 ++ */ ++ ++#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 ++ */ ++ ++#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 ++ */ ++ ++#ifndef _RSEQ_X86_THREAD_POINTER ++#define _RSEQ_X86_THREAD_POINTER ++ ++#include ++ ++#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.4/selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch b/queue-5.4/selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch new file mode 100644 index 00000000000..0e5c834ff96 --- /dev/null +++ b/queue-5.4/selftests-rseq-remove-arm-mips-asm-goto-compiler-work-around.patch @@ -0,0 +1,435 @@ +From 94c5cf2a0e193afffef8de48ddc42de6df7cac93 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:50 -0500 +Subject: selftests/rseq: Remove arm/mips asm goto compiler work-around + +From: Mathieu Desnoyers + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/lkml/20171121141900.18471-17-mathieu.desnoyers@efficios.com/ +Signed-off-by: Greg Kroah-Hartman +--- + 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.4/selftests-rseq-remove-array_size-define-from-individual-tests.patch b/queue-5.4/selftests-rseq-remove-array_size-define-from-individual-tests.patch new file mode 100644 index 00000000000..1e15002ff0b --- /dev/null +++ b/queue-5.4/selftests-rseq-remove-array_size-define-from-individual-tests.patch @@ -0,0 +1,52 @@ +From 07ad4f7629d4802ff0d962b0ac23ea6445964e2a Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 9 Dec 2021 16:19:09 -0700 +Subject: selftests/rseq: remove ARRAY_SIZE define from individual tests + +From: Shuah Khan + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + ++#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 + #include + ++#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.4/selftests-rseq-remove-useless-assignment-to-cpu-variable.patch b/queue-5.4/selftests-rseq-remove-useless-assignment-to-cpu-variable.patch new file mode 100644 index 00000000000..c92cb9d1ddc --- /dev/null +++ b/queue-5.4/selftests-rseq-remove-useless-assignment-to-cpu-variable.patch @@ -0,0 +1,30 @@ +From 930378d056eac2c96407b02aafe4938d0ac9cc37 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:41 -0500 +Subject: selftests/rseq: Remove useless assignment to cpu variable + +From: Mathieu Desnoyers + +commit 930378d056eac2c96407b02aafe4938d0ac9cc37 upstream. + +Signed-off-by: Mathieu Desnoyers +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-4-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -366,9 +366,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.4/selftests-rseq-remove-volatile-from-__rseq_abi.patch b/queue-5.4/selftests-rseq-remove-volatile-from-__rseq_abi.patch new file mode 100644 index 00000000000..ba15e79cf7a --- /dev/null +++ b/queue-5.4/selftests-rseq-remove-volatile-from-__rseq_abi.patch @@ -0,0 +1,65 @@ +From 94b80a19ebfe347a01301d750040a61c38200e2b Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:42 -0500 +Subject: selftests/rseq: Remove volatile from __rseq_abi + +From: Mathieu Desnoyers + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-5-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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.4/selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch b/queue-5.4/selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch new file mode 100644 index 00000000000..ca8cadc6d85 --- /dev/null +++ b/queue-5.4/selftests-rseq-uplift-rseq-selftests-for-compatibility-with-glibc-2.35.patch @@ -0,0 +1,282 @@ +From 233e667e1ae3e348686bd9dd0172e62a09d852e1 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Mon, 24 Jan 2022 12:12:45 -0500 +Subject: selftests/rseq: Uplift rseq selftests for compatibility with glibc-2.35 + +From: Mathieu Desnoyers + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-8-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + #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.4/selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch b/queue-5.4/selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch new file mode 100644 index 00000000000..d07f050f6fb --- /dev/null +++ b/queue-5.4/selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch @@ -0,0 +1,252 @@ +From 127b6429d235ab7c358223bbfd8a8b8d8cc799b6 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +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 + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-16-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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.4/selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch b/queue-5.4/selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch new file mode 100644 index 00000000000..a325e4c8e52 --- /dev/null +++ b/queue-5.4/selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch @@ -0,0 +1,219 @@ +From 4e15bb766b6c6e963a4d33629034d0ec3b7637df Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +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 + +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 +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20220124171253.22072-15-mathieu.desnoyers@efficios.com +Signed-off-by: Greg Kroah-Hartman +--- + 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), diff --git a/queue-5.4/series b/queue-5.4/series index 877be012c24..080d0dc5548 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -31,3 +31,20 @@ hwmon-ibmaem-don-t-call-platform_device_del-if-platf.patch net-dsa-bcm_sf2-force-pause-link-settings.patch sit-use-min.patch ipv6-sit-fix-ipip6_tunnel_get_prl-return-value.patch +rseq-selftests-x86_64-add-rseq_offset_deref_addv.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 -- 2.47.3