Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/rseq: Introduce thread pointer getters

This is done in preparation for the selftest uplift to become compatible
with glibc-2.35.

glibc-2.35 exposes the rseq per-thread data in the TCB, accessible
at an offset from the thread pointer.

The toolchains do not implement accessing the thread pointer on all
architectures. Provide thread pointer getters for ppc and x86 which
lack (or lacked until recently) toolchain support.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20220124171253.22072-7-mathieu.desnoyers@efficios.com

authored by

Mathieu Desnoyers and committed by
Peter Zijlstra
886ddfba e546cd48

+114
+25
tools/testing/selftests/rseq/rseq-generic-thread-pointer.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ 2 + /* 3 + * rseq-generic-thread-pointer.h 4 + * 5 + * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 6 + */ 7 + 8 + #ifndef _RSEQ_GENERIC_THREAD_POINTER 9 + #define _RSEQ_GENERIC_THREAD_POINTER 10 + 11 + #ifdef __cplusplus 12 + extern "C" { 13 + #endif 14 + 15 + /* Use gcc builtin thread pointer. */ 16 + static inline void *rseq_thread_pointer(void) 17 + { 18 + return __builtin_thread_pointer(); 19 + } 20 + 21 + #ifdef __cplusplus 22 + } 23 + #endif 24 + 25 + #endif
+30
tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ 2 + /* 3 + * rseq-ppc-thread-pointer.h 4 + * 5 + * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 6 + */ 7 + 8 + #ifndef _RSEQ_PPC_THREAD_POINTER 9 + #define _RSEQ_PPC_THREAD_POINTER 10 + 11 + #ifdef __cplusplus 12 + extern "C" { 13 + #endif 14 + 15 + static inline void *rseq_thread_pointer(void) 16 + { 17 + #ifdef __powerpc64__ 18 + register void *__result asm ("r13"); 19 + #else 20 + register void *__result asm ("r2"); 21 + #endif 22 + asm ("" : "=r" (__result)); 23 + return __result; 24 + } 25 + 26 + #ifdef __cplusplus 27 + } 28 + #endif 29 + 30 + #endif
+19
tools/testing/selftests/rseq/rseq-thread-pointer.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ 2 + /* 3 + * rseq-thread-pointer.h 4 + * 5 + * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 6 + */ 7 + 8 + #ifndef _RSEQ_THREAD_POINTER 9 + #define _RSEQ_THREAD_POINTER 10 + 11 + #if defined(__x86_64__) || defined(__i386__) 12 + #include "rseq-x86-thread-pointer.h" 13 + #elif defined(__PPC__) 14 + #include "rseq-ppc-thread-pointer.h" 15 + #else 16 + #include "rseq-generic-thread-pointer.h" 17 + #endif 18 + 19 + #endif
+40
tools/testing/selftests/rseq/rseq-x86-thread-pointer.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ 2 + /* 3 + * rseq-x86-thread-pointer.h 4 + * 5 + * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 6 + */ 7 + 8 + #ifndef _RSEQ_X86_THREAD_POINTER 9 + #define _RSEQ_X86_THREAD_POINTER 10 + 11 + #include <features.h> 12 + 13 + #ifdef __cplusplus 14 + extern "C" { 15 + #endif 16 + 17 + #if __GNUC_PREREQ (11, 1) 18 + static inline void *rseq_thread_pointer(void) 19 + { 20 + return __builtin_thread_pointer(); 21 + } 22 + #else 23 + static inline void *rseq_thread_pointer(void) 24 + { 25 + void *__result; 26 + 27 + # ifdef __x86_64__ 28 + __asm__ ("mov %%fs:0, %0" : "=r" (__result)); 29 + # else 30 + __asm__ ("mov %%gs:0, %0" : "=r" (__result)); 31 + # endif 32 + return __result; 33 + } 34 + #endif /* !GCC 11 */ 35 + 36 + #ifdef __cplusplus 37 + } 38 + #endif 39 + 40 + #endif