| From 886ddfba933f5ce9d76c278165d834d114ba4ffc Mon Sep 17 00:00:00 2001 |
| From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| Date: Mon, 24 Jan 2022 12:12:44 -0500 |
| Subject: selftests/rseq: Introduce thread pointer getters |
| |
| From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| |
| commit 886ddfba933f5ce9d76c278165d834d114ba4ffc upstream. |
| |
| This is done in preparation for the selftest uplift to become compatible |
| with glibc-2.35. |
| |
| glibc-2.35 exposes the rseq per-thread data in the TCB, accessible |
| at an offset from the thread pointer. |
| |
| The toolchains do not implement accessing the thread pointer on all |
| architectures. Provide thread pointer getters for ppc and x86 which |
| lack (or lacked until recently) toolchain support. |
| |
| Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> |
| Link: https://lkml.kernel.org/r/20220124171253.22072-7-mathieu.desnoyers@efficios.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| tools/testing/selftests/rseq/rseq-generic-thread-pointer.h | 25 ++++++++ |
| tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h | 30 +++++++++ |
| tools/testing/selftests/rseq/rseq-thread-pointer.h | 19 ++++++ |
| tools/testing/selftests/rseq/rseq-x86-thread-pointer.h | 40 +++++++++++++ |
| 4 files changed, 114 insertions(+) |
| create mode 100644 tools/testing/selftests/rseq/rseq-generic-thread-pointer.h |
| create mode 100644 tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h |
| create mode 100644 tools/testing/selftests/rseq/rseq-thread-pointer.h |
| create mode 100644 tools/testing/selftests/rseq/rseq-x86-thread-pointer.h |
| |
| --- /dev/null |
| +++ b/tools/testing/selftests/rseq/rseq-generic-thread-pointer.h |
| @@ -0,0 +1,25 @@ |
| +/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ |
| +/* |
| + * rseq-generic-thread-pointer.h |
| + * |
| + * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| + */ |
| + |
| +#ifndef _RSEQ_GENERIC_THREAD_POINTER |
| +#define _RSEQ_GENERIC_THREAD_POINTER |
| + |
| +#ifdef __cplusplus |
| +extern "C" { |
| +#endif |
| + |
| +/* Use gcc builtin thread pointer. */ |
| +static inline void *rseq_thread_pointer(void) |
| +{ |
| + return __builtin_thread_pointer(); |
| +} |
| + |
| +#ifdef __cplusplus |
| +} |
| +#endif |
| + |
| +#endif |
| --- /dev/null |
| +++ b/tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h |
| @@ -0,0 +1,30 @@ |
| +/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ |
| +/* |
| + * rseq-ppc-thread-pointer.h |
| + * |
| + * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| + */ |
| + |
| +#ifndef _RSEQ_PPC_THREAD_POINTER |
| +#define _RSEQ_PPC_THREAD_POINTER |
| + |
| +#ifdef __cplusplus |
| +extern "C" { |
| +#endif |
| + |
| +static inline void *rseq_thread_pointer(void) |
| +{ |
| +#ifdef __powerpc64__ |
| + register void *__result asm ("r13"); |
| +#else |
| + register void *__result asm ("r2"); |
| +#endif |
| + asm ("" : "=r" (__result)); |
| + return __result; |
| +} |
| + |
| +#ifdef __cplusplus |
| +} |
| +#endif |
| + |
| +#endif |
| --- /dev/null |
| +++ b/tools/testing/selftests/rseq/rseq-thread-pointer.h |
| @@ -0,0 +1,19 @@ |
| +/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ |
| +/* |
| + * rseq-thread-pointer.h |
| + * |
| + * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| + */ |
| + |
| +#ifndef _RSEQ_THREAD_POINTER |
| +#define _RSEQ_THREAD_POINTER |
| + |
| +#if defined(__x86_64__) || defined(__i386__) |
| +#include "rseq-x86-thread-pointer.h" |
| +#elif defined(__PPC__) |
| +#include "rseq-ppc-thread-pointer.h" |
| +#else |
| +#include "rseq-generic-thread-pointer.h" |
| +#endif |
| + |
| +#endif |
| --- /dev/null |
| +++ b/tools/testing/selftests/rseq/rseq-x86-thread-pointer.h |
| @@ -0,0 +1,40 @@ |
| +/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ |
| +/* |
| + * rseq-x86-thread-pointer.h |
| + * |
| + * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| + */ |
| + |
| +#ifndef _RSEQ_X86_THREAD_POINTER |
| +#define _RSEQ_X86_THREAD_POINTER |
| + |
| +#include <features.h> |
| + |
| +#ifdef __cplusplus |
| +extern "C" { |
| +#endif |
| + |
| +#if __GNUC_PREREQ (11, 1) |
| +static inline void *rseq_thread_pointer(void) |
| +{ |
| + return __builtin_thread_pointer(); |
| +} |
| +#else |
| +static inline void *rseq_thread_pointer(void) |
| +{ |
| + void *__result; |
| + |
| +# ifdef __x86_64__ |
| + __asm__ ("mov %%fs:0, %0" : "=r" (__result)); |
| +# else |
| + __asm__ ("mov %%gs:0, %0" : "=r" (__result)); |
| +# endif |
| + return __result; |
| +} |
| +#endif /* !GCC 11 */ |
| + |
| +#ifdef __cplusplus |
| +} |
| +#endif |
| + |
| +#endif |