summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2021-12-09 09:49:32 +0100
committerFlorian Weimer <fweimer@redhat.com>2021-12-09 09:49:32 +0100
commit95e114a0919d844d8fe07839cb6538b7f5ee920e (patch)
tree530964270c0a6baf1dd741e00c4f5f205631d70e /nptl
parent8d1927d8dc5aad0f01c929123086be3a5b799d18 (diff)
downloadglibc-95e114a0919d844d8fe07839cb6538b7f5ee920e.tar.gz
glibc-95e114a0919d844d8fe07839cb6538b7f5ee920e.tar.xz
glibc-95e114a0919d844d8fe07839cb6538b7f5ee920e.zip
nptl: Add rseq registration
The rseq area is placed directly into struct pthread.  rseq
registration failure is not treated as an error, so it is possible
that threads run with inconsistent registration status.

<sys/rseq.h> is not yet installed as a public header.

Co-Authored-By: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Diffstat (limited to 'nptl')
-rw-r--r--nptl/descr.h4
-rw-r--r--nptl/pthread_create.c13
2 files changed, 17 insertions, 0 deletions
diff --git a/nptl/descr.h b/nptl/descr.h
index af2a6ab87a..92db305913 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -34,6 +34,7 @@
 #include <bits/types/res_state.h>
 #include <kernel-features.h>
 #include <tls-internal-struct.h>
+#include <sys/rseq.h>
 
 #ifndef TCB_ALIGNMENT
 # define TCB_ALIGNMENT 32
@@ -406,6 +407,9 @@ struct pthread
   /* Used on strsignal.  */
   struct tls_internal_t tls_state;
 
+  /* rseq area registered with the kernel.  */
+  struct rseq rseq_area;
+
   /* This member must be last.  */
   char end_padding[];
 
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index bad9eeb52f..ea0d79341e 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -32,6 +32,7 @@
 #include <default-sched.h>
 #include <futex-internal.h>
 #include <tls-setup.h>
+#include <rseq-internal.h>
 #include "libioP.h"
 #include <sys/single_threaded.h>
 #include <version.h>
@@ -366,6 +367,9 @@ start_thread (void *arg)
   /* Initialize pointers to locale data.  */
   __ctype_init ();
 
+  /* Register rseq TLS to the kernel.  */
+  rseq_register_current_thread (pd);
+
 #ifndef __ASSUME_SET_ROBUST_LIST
   if (__nptl_set_robust_list_avail)
 #endif
@@ -571,6 +575,15 @@ out:
      process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID
      flag.  The 'tid' field in the TCB will be set to zero.
 
+     rseq TLS is still registered at this point.  Rely on implicit
+     unregistration performed by the kernel on thread teardown.  This is not a
+     problem because the rseq TLS lives on the stack, and the stack outlives
+     the thread.  If TCB allocation is ever changed, additional steps may be
+     required, such as performing explicit rseq unregistration before
+     reclaiming the rseq TLS area memory.  It is NOT sufficient to block
+     signals because the kernel may write to the rseq area even without
+     signals.
+
      The exit code is zero since in case all threads exit by calling
      'pthread_exit' the exit status must be 0 (zero).  */
   while (1)