Skip to content

Commit

Permalink
selftests/rseq: Introduce thread pointer getters
Browse files Browse the repository at this point in the history
commit 886ddfb 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>
  • Loading branch information
compudj authored and gregkh committed Jul 7, 2022
1 parent 4a78bf8 commit c79e564
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
25 changes: 25 additions & 0 deletions tools/testing/selftests/rseq/rseq-generic-thread-pointer.h
Original file line number Diff line number Diff line change
@@ -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
30 changes: 30 additions & 0 deletions tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions tools/testing/selftests/rseq/rseq-thread-pointer.h
Original file line number Diff line number Diff line change
@@ -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
40 changes: 40 additions & 0 deletions tools/testing/selftests/rseq/rseq-x86-thread-pointer.h
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit c79e564

Please sign in to comment.