[PATCH v13 5/6] nptl: Move the rseq area to the 'extra TLS' block

Mathieu Desnoyers mathieu.desnoyers@efficios.com
Tue Nov 19 20:46:55 GMT 2024


On 2024-11-19 13:58, Michael Jeanson wrote:
> Move the rseq area to the newly added 'extra TLS' block, this is the
> last step in adding support for the rseq extended ABI. The size of the
> rseq area is now dynamic and depends on the rseq features reported by
> the kernel through the elf auxiliary vector. This will allow
> applications to use rseq features past the 32 bytes of the original rseq
> ABI as they become available in future kernels.
> 
> Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
> ---
> Changes since v12:
> - Style nits, missing spaces before '(' in function macro/calls
> - Add comment and variable array member to 'struct rseq_area'
> - Comment and style nits in tst-rseq-disable.c
> Changes since v11:
> - __rseq_size is now set directly in _dl_parse_auxv, set it to 0 when
>    the main thread registration fails or is disabled by tunable
> ---
>   nptl/pthread_create.c                         |  2 +-
>   sysdeps/nptl/dl-tls_init_tp.c                 |  9 --
>   sysdeps/unix/sysv/linux/Makefile              | 10 +++
>   sysdeps/unix/sysv/linux/dl-parse_auxv.h       | 12 +--
>   sysdeps/unix/sysv/linux/rseq-internal.h       | 48 ++++++++---
>   sysdeps/unix/sysv/linux/sched_getcpu.c        |  3 +-
>   .../unix/sysv/linux/tst-rseq-disable-static.c |  1 +
>   sysdeps/unix/sysv/linux/tst-rseq-disable.c    | 64 +++++++++++---
>   .../unix/sysv/linux/tst-rseq-nptl-static.c    |  1 +
>   sysdeps/unix/sysv/linux/tst-rseq-static.c     |  1 +
>   sysdeps/unix/sysv/linux/tst-rseq.c            | 84 +++++++++++++++----
>   sysdeps/unix/sysv/linux/tst-rseq.h            |  2 +-
>   12 files changed, 180 insertions(+), 57 deletions(-)
>   create mode 100644 sysdeps/unix/sysv/linux/tst-rseq-disable-static.c
>   create mode 100644 sysdeps/unix/sysv/linux/tst-rseq-nptl-static.c
>   create mode 100644 sysdeps/unix/sysv/linux/tst-rseq-static.c
> 
> diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
> index ef3ec33290..dd11a9fa46 100644
> --- a/nptl/pthread_create.c
> +++ b/nptl/pthread_create.c
> @@ -696,7 +696,7 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
>   
>     /* Inherit rseq registration state.  Without seccomp filters, rseq
>        registration will either always fail or always succeed.  */
> -  if ((int) THREAD_GETMEM_VOLATILE (self, rseq_area.cpu_id) >= 0)
> +  if ((int) RSEQ_GETMEM_VOLATILE (cpu_id) >= 0)
>       pd->flags |= ATTR_FLAG_DO_RSEQ;
>   
>     /* Initialize the field for the ID of the thread which is waiting
> diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
> index 2a338bd7df..4cb3d853cd 100644
> --- a/sysdeps/nptl/dl-tls_init_tp.c
> +++ b/sysdeps/nptl/dl-tls_init_tp.c
> @@ -110,15 +110,6 @@ __tls_init_tp (void)
>       do_rseq = TUNABLE_GET (rseq, int, NULL);
>       if (!rseq_register_current_thread (pd, do_rseq))
>         _rseq_size = 0;
> -
> -#ifdef RSEQ_SIG
> -    /* This should be a compile-time constant, but the current
> -       infrastructure makes it difficult to determine its value.  Not
> -       all targets support __thread_pointer, so set __rseq_offset only
> -       if the rseq registration may have happened because RSEQ_SIG is
> -       defined.  */
> -    _rseq_offset = (char *) &pd->rseq_area - (char *) __thread_pointer ();
> -#endif
>     }
>   
>     /* Set initial thread's stack block from 0 up to __libc_stack_end.
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 527c7a5ae8..ea0e712011 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -267,6 +267,11 @@ tests-internal += \
>     tst-rseq-disable \
>     # tests-internal
>   
> +tests-static += \
> +  tst-rseq-disable-static \
> +  tst-rseq-static \
> +  # tests-static
> +
>   tests-time64 += \
>     tst-adjtimex-time64 \
>     tst-clock_adjtime-time64 \
> @@ -410,6 +415,7 @@ $(objpfx)tst-sched-consts.out: ../sysdeps/unix/sysv/linux/tst-sched-consts.py
>   $(objpfx)tst-sched-consts.out: $(sysdeps-linux-python-deps)
>   
>   tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0
> +tst-rseq-disable-static-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0
>   
>   endif # $(subdir) == misc
>   
> @@ -675,4 +681,8 @@ tests += \
>   tests-internal += \
>     tst-rseq-nptl \
>     # tests-internal
> +
> +tests-static += \
> +  tst-rseq-nptl-static \
> +  # tests-static
>   endif
> diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h
> index 5a0ef0ae2a..8657cf7b2f 100644
> --- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h
> +++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h
> @@ -61,15 +61,9 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values)
>   #endif
>   
>     /* Get the rseq feature size, with a minimum of RSEQ_AREA_SIZE_INITIAL_USED
> -     (20) for kernels that don't have AT_RSEQ_FEATURE_SIZE.  Limit the feature
> -     size to RSEQ_AREA_SIZE_MAX_USED (28) which fits the rseq area in 'struct
> -     pthread' and represents the maximum feature size of currently released
> -     kernels.  Since no kernels currently cross the 32 bytes of the original
> -     ABI, the semantics of a feature size of 32 or more are still undetermined.
> -     */
> -  _rseq_size = MIN (MAX (auxv_values[AT_RSEQ_FEATURE_SIZE],
> -                         RSEQ_AREA_SIZE_INITIAL_USED),
> -		    RSEQ_AREA_SIZE_MAX_USED);
> +     (20) for kernels that don't have AT_RSEQ_FEATURE_SIZE.  */
> +  _rseq_size = MAX (auxv_values[AT_RSEQ_FEATURE_SIZE],
> +                    RSEQ_AREA_SIZE_INITIAL_USED);
>     _rseq_align = MAX (auxv_values[AT_RSEQ_ALIGN], RSEQ_MIN_ALIGN);
>   
>     DL_PLATFORM_AUXV
> diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
> index 41a6bd63f1..b602bdb89e 100644
> --- a/sysdeps/unix/sysv/linux/rseq-internal.h
> +++ b/sysdeps/unix/sysv/linux/rseq-internal.h
> @@ -26,6 +26,31 @@
>   #include <thread_pointer.h>
>   #include <tcb-access.h>
>   #include <sys/rseq.h>
> +#include <thread_pointer.h>
> +#include <ldsodefs.h>
> +
> +/* rseq area registered with the kernel.  Use a custom definition here to
> +   isolate from the system provided header which could lack some fields of the
> +   Extended ABI.
> +
> +   This is only used to get the field offsets and sizes, it should never be
> +   used for direct object allocations.
> +
> +   Access to fields of the Extended ABI beyond the 20 bytes of the original ABI
> +   (after 'flags') must be gated by a check of the feature size.  */
> +struct rseq_area
> +{
> +  /* Original ABI.  */
> +  uint32_t cpu_id_start;
> +  uint32_t cpu_id;
> +  uint64_t rseq_cs;
> +  uint32_t flags;
> +  /* Extended ABI.  */
> +  uint32_t node_id;
> +  uint32_t mm_cid;
> +  /* Flexible array member to discourage direct object allocations.  */
> +  char end[];
> +};
>   
>   /* Minimum size of the rseq area allocation required by the syscall.  The
>      actually used rseq feature size may be less (20 bytes initially).  */
> @@ -47,10 +72,12 @@ extern size_t _rseq_align attribute_hidden;
>   
>   /* Size of the active features in the rseq area.
>      Populated from the auxiliary vector with a minimum of '20'.
> +   Set to '0' on registration failure of the main thread.
>      In .data.relro but not yet write-protected.  */
>   extern unsigned int _rseq_size attribute_hidden;
>   
> -/* Offset from the thread pointer to the rseq area.
> +/* Offset from the thread pointer to the rseq area, always set to allow
> +   checking the registration status by reading the 'cpu_id' field.
>      In .data.relro but not yet write-protected.  */
>   extern ptrdiff_t _rseq_offset attribute_hidden;
>   
> @@ -75,33 +102,34 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq)
>       {
>         unsigned int size =  __rseq_size;
>   
> +      /* The feature size can be smaller than the minimum rseq area size of 32
> +         bytes accepted by the syscall, if this is the case, bump the size of
> +         the registration to the minimum. The 'extra TLS' block is always at
> +         least 32 bytes. */
>         if (size < RSEQ_AREA_SIZE_INITIAL)
> -        /* The initial implementation used only 20 bytes out of 32,
> -           but still expected size 32.  */
>           size = RSEQ_AREA_SIZE_INITIAL;
>   
>         /* Initialize the rseq fields that are read by the kernel on
>            registration, there is no guarantee that struct pthread is
>            cleared on all architectures.  */

The kernel only cares about rseq_cs and flags fields initialization on
registration­. I understand that the code below is trying to be more
robust by initializing cpu_id as well. Why not initialize the
cpu_id_start field as well then ?

> -      THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_UNINITIALIZED);
> -      THREAD_SETMEM (self, rseq_area.rseq_cs, 0);
> -      THREAD_SETMEM (self, rseq_area.flags, 0);
> +      RSEQ_SETMEM (cpu_id, RSEQ_CPU_ID_UNINITIALIZED);
> +      RSEQ_SETMEM (rseq_cs, 0);

This won't work on 32-bit if we disallow the volatile setmem of 64-bit.
This would be a use-case for a non-volatile RSEQ_SETMEM.

> +      RSEQ_SETMEM (flags, 0);
>   
> -      int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area,
> -                                       size, 0, RSEQ_SIG);
> +      int ret = INTERNAL_SYSCALL_CALL (rseq, RSEQ_SELF (), size, 0, RSEQ_SIG);

ok

>         if (!INTERNAL_SYSCALL_ERROR_P (ret))
>           return true;
>       }
>     /* When rseq is disabled by tunables or the registration fails, inform
>        userspace by setting 'cpu_id' to RSEQ_CPU_ID_REGISTRATION_FAILED.  */
> -  THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
> +  RSEQ_SETMEM (cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);

ok

>     return false;
>   }
>   #else /* RSEQ_SIG */
>   static inline bool
>   rseq_register_current_thread (struct pthread *self, bool do_rseq)
>   {
> -  THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
> +  RSEQ_SETMEM (cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);

ok

>     return false;
>   }
>   #endif /* RSEQ_SIG */
> diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c
> index 72a3360550..18a7817148 100644
> --- a/sysdeps/unix/sysv/linux/sched_getcpu.c
> +++ b/sysdeps/unix/sysv/linux/sched_getcpu.c
> @@ -19,6 +19,7 @@
>   #include <sched.h>
>   #include <sysdep.h>
>   #include <sysdep-vdso.h>
> +#include <rseq-internal.h>
>   
>   static int
>   vsyscall_sched_getcpu (void)
> @@ -36,6 +37,6 @@ vsyscall_sched_getcpu (void)
>   int
>   sched_getcpu (void)
>   {
> -  int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id);
> +  int cpu_id = RSEQ_GETMEM_VOLATILE (cpu_id);

ok

>     return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu ();
>   }
> diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable-static.c b/sysdeps/unix/sysv/linux/tst-rseq-disable-static.c
> new file mode 100644
> index 0000000000..2687d13d3d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-rseq-disable-static.c
> @@ -0,0 +1 @@
> +#include "tst-rseq-disable.c"
> diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
> index bbc655bec4..ad8563ade7 100644
> --- a/sysdeps/unix/sysv/linux/tst-rseq-disable.c
> +++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
> @@ -26,32 +26,69 @@
>   #include <unistd.h>
>   
>   #ifdef RSEQ_SIG
> +# include <sys/auxv.h>
> +# include "tst-rseq.h"
> +
> +/* Used to test private registration with the rseq system call because glibc
> +   rseq is disabled.  */
> +static __thread struct rseq local_rseq = {
> +  .cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED,
> +};
>   
>   /* Check that rseq can be registered and has not been taken by glibc.  */
>   static void
>   check_rseq_disabled (void)
>   {
> -  struct pthread *pd = THREAD_SELF;
> +  struct rseq *rseq_abi = (struct rseq *) ((char *) __thread_pointer () +
> +		           __rseq_offset);
> +
> +#if TLS_TCB_AT_TP
> +  /* The rseq area block should come before the thread pointer and be at least
> +     32 bytes. */
> +  TEST_VERIFY (__rseq_offset <= RSEQ_AREA_SIZE_INITIAL);

I find this comparison unexpected. Shouldn't we check that __rseq_offset
is negative, and below a certain (negated) size here ?

> +#elif TLS_DTV_AT_TP
> +  /* The rseq area block should come after the thread pointer. */
> +  TEST_VERIFY (__rseq_offset >= 0);
> +#else
> +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
> +#endif
>   
> +  /* __rseq_flags is unused and should always be '0'.  */
>     TEST_COMPARE (__rseq_flags, 0);
> -  TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset
> -               == (char *) &pd->rseq_area);
> +
> +  /* When rseq is not registered, __rseq_size should always be '0'.  */
>     TEST_COMPARE (__rseq_size, 0);
> -  TEST_COMPARE ((int) pd->rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
>   
> -  int ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area),
> -                     0, RSEQ_SIG);
> +  /* When rseq is not registered, the 'cpu_id' field should be set to
> +     RSEQ_CPU_ID_REGISTRATION_FAILED.  */
> +  TEST_COMPARE ((int) rseq_abi->cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
> +
> +  /* Test a rseq registration which should succeed since the internal
> +     registration is disabled.  */
> +  int ret = syscall (__NR_rseq, &local_rseq, RSEQ_AREA_SIZE_INITIAL, 0, RSEQ_SIG);
>     if (ret == 0)
>       {
> -      ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area),
> +      /* A successful registration should set the cpu id.  */
> +      TEST_VERIFY (local_rseq.cpu_id >= 0);
> +
> +      /* Test we can also unregister rseq.  */
> +      ret = syscall (__NR_rseq, &local_rseq, RSEQ_AREA_SIZE_INITIAL,
>                        RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
>         TEST_COMPARE (ret, 0);
> -      pd->rseq_area.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
>       }
>     else
>       {
> -      TEST_VERIFY (errno != -EINVAL);
> -      TEST_VERIFY (errno != -EBUSY);
> +      /* Check if we failed with EINVAL which would mean an invalid rseq flags,
> +         a mis-aligned rseq area address or an incorrect rseq size.  */
> +      TEST_VERIFY (errno != EINVAL);
> +
> +      /* Check if we failed with EBUSY which means an existing rseq
> +         registration. */
> +      TEST_VERIFY (errno != EBUSY);
> +
> +      /* Check if we failed with EFAULT which means an invalid rseq area
> +         address.  */
> +      TEST_VERIFY (errno != EFAULT);

ok

>       }
>   }
>   
> @@ -71,6 +108,13 @@ proc_func (void *ignored)
>   static int
>   do_test (void)
>   {
> +  printf ("info: __rseq_size: %u\n", __rseq_size);
> +  printf ("info: __rseq_offset: %td\n", __rseq_offset);
> +  printf ("info: __rseq_flags: %u\n", __rseq_flags);
> +  printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n",
> +          getauxval (AT_RSEQ_FEATURE_SIZE));
> +  printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN));

ok

> +
>     puts ("info: checking main thread");
>     check_rseq_disabled ();
>   
> diff --git a/sysdeps/unix/sysv/linux/tst-rseq-nptl-static.c b/sysdeps/unix/sysv/linux/tst-rseq-nptl-static.c
> new file mode 100644
> index 0000000000..6e2c923bb9
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-rseq-nptl-static.c
> @@ -0,0 +1 @@
> +#include "tst-rseq-nptl.c"
> diff --git a/sysdeps/unix/sysv/linux/tst-rseq-static.c b/sysdeps/unix/sysv/linux/tst-rseq-static.c
> new file mode 100644
> index 0000000000..1d97f3bd3d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-rseq-static.c
> @@ -0,0 +1 @@
> +#include "tst-rseq.c"
> diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c
> index d1ae16b953..1a7aae6cc8 100644
> --- a/sysdeps/unix/sysv/linux/tst-rseq.c
> +++ b/sysdeps/unix/sysv/linux/tst-rseq.c
> @@ -19,6 +19,8 @@
>      not linked against libpthread.  */
>   
>   #include <support/check.h>
> +#include <support/namespace.h>
> +#include <support/xthread.h>
>   #include <stdio.h>
>   #include <sys/rseq.h>
>   #include <unistd.h>
> @@ -32,25 +34,69 @@
>   # include <sys/auxv.h>
>   # include <thread_pointer.h>
>   # include <tls.h>
> +# include <sys/auxv.h>
>   # include "tst-rseq.h"
>   
>   static void
>   do_rseq_main_test (void)
>   {
> -  struct pthread *pd = THREAD_SELF;
> -  size_t rseq_feature_size = MIN (MAX (getauxval (AT_RSEQ_FEATURE_SIZE),
> -                                       RSEQ_AREA_SIZE_INITIAL_USED),
> -                                  RSEQ_AREA_SIZE_MAX_USED);
> +  size_t rseq_align = MAX (getauxval (AT_RSEQ_ALIGN), RSEQ_MIN_ALIGN);
> +  size_t rseq_feature_size = MAX (getauxval (AT_RSEQ_FEATURE_SIZE),
> +                                  RSEQ_AREA_SIZE_INITIAL_USED);
> +  size_t rseq_alloc_size = roundup (MAX (rseq_feature_size,
> +                                    RSEQ_AREA_SIZE_INITIAL_USED), rseq_align);
> +  struct rseq *rseq_abi = __thread_pointer () + __rseq_offset;
>   
>     TEST_VERIFY_EXIT (rseq_thread_registered ());
> +
> +  /* __rseq_flags is unused and should always be '0'.  */
>     TEST_COMPARE (__rseq_flags, 0);
> -  TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset
> -               == (char *) &pd->rseq_area);
> +
> +  /* When rseq is registered, __rseq_size should report the feature size.  */
>     TEST_COMPARE (__rseq_size, rseq_feature_size);
> +
> +  /* When rseq is registered, the 'cpu_id' field should be set to a valid cpu
> +   * number.  */
> +  TEST_VERIFY ((int32_t) rseq_abi->cpu_id >= 0);
> +
> +  /* The rseq area address must be aligned.  */
> +  TEST_VERIFY (((unsigned long) rseq_abi % rseq_align) == 0);
> +
> +#if TLS_TCB_AT_TP
> +  /* The rseq area block should come before the thread pointer and be at least
> +     32 bytes. */
> +  TEST_VERIFY (__rseq_offset <= RSEQ_AREA_SIZE_INITIAL);

same comment as above about missing negation here ?

> +#elif TLS_DTV_AT_TP
> +  /* The rseq area block should come after the thread pointer. */
> +  TEST_VERIFY (__rseq_offset >= 0);
> +#else
> +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
> +#endif
> +
> +  /* Test a rseq registration with the same arguments as the internal
> +     registration which should fail with errno == EBUSY.  */
> +  TEST_VERIFY (((unsigned long) rseq_abi % rseq_align) == 0);
> +  TEST_VERIFY (__rseq_size <= rseq_alloc_size);
> +  int ret = syscall (__NR_rseq, rseq_abi, rseq_alloc_size, 0, RSEQ_SIG);
> +  TEST_VERIFY (ret != 0);
> +  TEST_COMPARE (errno, EBUSY);

ok

> +}
> +
> +static void *
> +thread_func (void *ignored)
> +{
> +  do_rseq_main_test ();
> +  return NULL;
>   }
>   
>   static void
> -do_rseq_test (void)
> +proc_func (void *ignored)
> +{
> +  do_rseq_main_test ();
> +}
> +
> +static int
> +do_test (void)
>   {
>     if (!rseq_available ())
>       {
> @@ -62,21 +108,27 @@ do_rseq_test (void)
>     printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n",
>             getauxval (AT_RSEQ_FEATURE_SIZE));
>     printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN));
> +
> +  puts ("info: checking main thread");
> +  do_rseq_main_test ();
> +
> +  puts ("info: checking main thread (2)");
>     do_rseq_main_test ();
> +
> +  puts ("info: checking new thread");
> +  xpthread_join (xpthread_create (NULL, thread_func, NULL));
> +
> +  puts ("info: checking subprocess");
> +  support_isolate_in_subprocess (proc_func, NULL);
> +
> +  return 0;
>   }
>   #else /* RSEQ_SIG */
> -static void
> -do_rseq_test (void)
> -{
> -  FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test");
> -}
> -#endif /* RSEQ_SIG */

ok

> -
>   static int
>   do_test (void)
>   {
> -  do_rseq_test ();
> -  return 0;
> +  FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test");
>   }
> +#endif /* RSEQ_SIG */
>   
>   #include <support/test-driver.c>
> diff --git a/sysdeps/unix/sysv/linux/tst-rseq.h b/sysdeps/unix/sysv/linux/tst-rseq.h
> index 7f82554e83..75dd8efb2e 100644
> --- a/sysdeps/unix/sysv/linux/tst-rseq.h
> +++ b/sysdeps/unix/sysv/linux/tst-rseq.h
> @@ -28,7 +28,7 @@
>   static inline bool
>   rseq_thread_registered (void)
>   {
> -  return THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id) >= 0;
> +  return RSEQ_GETMEM_VOLATILE (cpu_id) >= 0;

ok

Thanks,

Mathieu

>   }
>   
>   static inline int

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com



More information about the Libc-alpha mailing list