diff mbox series

[v8,3/8] nptl: Add public __rseq_feature_size symbol

Message ID 20240206162801.882585-4-mjeanson@efficios.com
State New
Headers show
Series Extend rseq support | expand

Commit Message

Michael Jeanson Feb. 6, 2024, 4:27 p.m. UTC
Exposing this symbol allows applications wishing to use rseq features
which are part of the extensible rseq ABI like 'node_id' and 'mm_cid' to
test the two following conditions in a single load / conditional branch:

- rseq is registered
- the specific rseq feature is available

This is useful as rseq is expected to be used in hot paths.

This variable is either zero (if restartable sequence registration
failed or has been disabled) or the size of the available restartable
sequence features.

Changes since v7:
* Fix sorting of symbols in abilist files

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
---
 csu/rseq-sizes.sym                              |  3 +++
 elf/dl-rseq-symbols.S                           | 17 +++++++++++++++++
 manual/threads.texi                             |  8 ++++++++
 sysdeps/nptl/dl-tls_init_tp.c                   |  2 ++
 sysdeps/unix/sysv/linux/Versions                |  3 +++
 sysdeps/unix/sysv/linux/aarch64/ld.abilist      |  1 +
 sysdeps/unix/sysv/linux/alpha/ld.abilist        |  1 +
 sysdeps/unix/sysv/linux/arc/ld.abilist          |  1 +
 sysdeps/unix/sysv/linux/arm/be/ld.abilist       |  1 +
 sysdeps/unix/sysv/linux/arm/le/ld.abilist       |  1 +
 sysdeps/unix/sysv/linux/csky/ld.abilist         |  1 +
 sysdeps/unix/sysv/linux/hppa/ld.abilist         |  1 +
 sysdeps/unix/sysv/linux/i386/ld.abilist         |  1 +
 .../unix/sysv/linux/loongarch/lp64/ld.abilist   |  1 +
 .../unix/sysv/linux/m68k/coldfire/ld.abilist    |  1 +
 sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist  |  1 +
 sysdeps/unix/sysv/linux/microblaze/ld.abilist   |  1 +
 sysdeps/unix/sysv/linux/mips/mips32/ld.abilist  |  1 +
 .../unix/sysv/linux/mips/mips64/n32/ld.abilist  |  1 +
 .../unix/sysv/linux/mips/mips64/n64/ld.abilist  |  1 +
 sysdeps/unix/sysv/linux/nios2/ld.abilist        |  1 +
 sysdeps/unix/sysv/linux/or1k/ld.abilist         |  1 +
 .../sysv/linux/powerpc/powerpc32/ld.abilist     |  1 +
 .../sysv/linux/powerpc/powerpc64/be/ld.abilist  |  1 +
 .../sysv/linux/powerpc/powerpc64/le/ld.abilist  |  1 +
 sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist   |  1 +
 sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist   |  1 +
 sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist |  1 +
 sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist |  1 +
 sysdeps/unix/sysv/linux/sh/be/ld.abilist        |  1 +
 sysdeps/unix/sysv/linux/sh/le/ld.abilist        |  1 +
 .../unix/sysv/linux/sparc/sparc32/ld.abilist    |  1 +
 .../unix/sysv/linux/sparc/sparc64/ld.abilist    |  1 +
 sysdeps/unix/sysv/linux/sys/rseq.h              |  4 ++++
 sysdeps/unix/sysv/linux/tst-rseq-disable.c      |  1 +
 sysdeps/unix/sysv/linux/tst-rseq.c              |  4 +++-
 sysdeps/unix/sysv/linux/x86_64/64/ld.abilist    |  1 +
 sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist   |  1 +
 38 files changed, 71 insertions(+), 1 deletion(-)

Comments

DJ Delorie Feb. 16, 2024, 10:07 p.m. UTC | #1
* Suggestion for manual entry
* attributes on externs
* comment about _rseq_feature_size default

Michael Jeanson <mjeanson@efficios.com> writes:
> +RSEQ_FEATURE_SIZE_SIZE		sizeof (unsigned int)
> +RSEQ_FEATURE_SIZE_ALIGN		__alignof (unsigned int)
> +

Ok.

> diff --git a/elf/dl-rseq-symbols.S b/elf/dl-rseq-symbols.S
> index 2d8e88367f..709188ae22 100644
> --- a/elf/dl-rseq-symbols.S
> +++ b/elf/dl-rseq-symbols.S
> @@ -38,6 +38,23 @@ __rseq_size:
>  _rseq_size:
>  	.zero	RSEQ_SIZE_SIZE
>  
> +/* Define 2 symbols, __rseq_feature_size is public const and
> +   _rseq_feature_size, which is an alias of __rseq_feature_size, but hidden and
> +   writable for internal use.  */
> +
> +	.globl	__rseq_feature_size
> +	.type	__rseq_feature_size, %object
> +	.size	__rseq_feature_size, RSEQ_FEATURE_SIZE_SIZE
> +	.hidden _rseq_feature_size
> +	.globl	_rseq_feature_size
> +	.type	_rseq_feature_size, %object
> +	.size	_rseq_feature_size, RSEQ_FEATURE_SIZE_SIZE
> +	.section .data.rel.ro
> +	.balign	RSEQ_FEATURE_SIZE_ALIGN
> +__rseq_feature_size:
> +_rseq_feature_size:
> +	.zero	RSEQ_FEATURE_SIZE_SIZE
> +

Ok.

> diff --git a/manual/threads.texi b/manual/threads.texi

> +@deftypevar {unsigned int} __rseq_feature_size
> +@standards{Linux, sys/rseq.h}
> +This variable is either zero (if restartable sequence registration
> +failed or has been disabled) or the size of the restartable sequence
> +features.  If registration is successful, @code{__rseq_feature_size}
> +is at least 20 (the initial feature size of @code{struct rseq}).
> +@end deftypevar

Perhaps a note about where the magic value '20' comes from, and how to
change it?  (Yes, *I* know it comes from the kernel, but the reader
might not)

> diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
> +extern unsigned int _rseq_feature_size attribute_relro attribute_hidden;

Again with attributes on externs.

> @@ -108,6 +109,7 @@ __tls_init_tp (void)
>      if (rseq_register_current_thread (pd, do_rseq))
>        {
>          _rseq_size = GLRO (dl_tls_rseq_size);
> +        _rseq_feature_size = GLRO (dl_tls_rseq_feature_size);
>        }

Ok.  Note "comment needed here" from our other mail thread ;-)

> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> +  GLIBC_2.40 {
> +    __rseq_feature_size;
> +  }

Ok.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
> index 5151c0781d..93039b756d 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist
> index 3e296c5473..fc67e31293 100644
> --- a/sysdeps/unix/sysv/linux/alpha/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.4 __stack_chk_guard D 0x8
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/arc/ld.abilist b/sysdeps/unix/sysv/linux/arc/ld.abilist
> index 55f0c2ab9c..31156b6ee1 100644
> --- a/sysdeps/unix/sysv/linux/arc/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/arm/be/ld.abilist b/sysdeps/unix/sysv/linux/arm/be/ld.abilist
> index f1da2c636d..3d16fa60db 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.4 __stack_chk_guard D 0x4
>  GLIBC_2.4 __tls_get_addr F
>  GLIBC_2.4 _dl_mcount F
>  GLIBC_2.4 _r_debug D 0x14
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/arm/le/ld.abilist b/sysdeps/unix/sysv/linux/arm/le/ld.abilist
> index f1da2c636d..3d16fa60db 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.4 __stack_chk_guard D 0x4
>  GLIBC_2.4 __tls_get_addr F
>  GLIBC_2.4 _dl_mcount F
>  GLIBC_2.4 _r_debug D 0x14
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/csky/ld.abilist b/sysdeps/unix/sysv/linux/csky/ld.abilist
> index 7f482276ed..088f000c4e 100644
> --- a/sysdeps/unix/sysv/linux/csky/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/hppa/ld.abilist b/sysdeps/unix/sysv/linux/hppa/ld.abilist
> index 7f5527fb30..8ae26c46c1 100644
> --- a/sysdeps/unix/sysv/linux/hppa/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.4 __stack_chk_guard D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist
> index 9c4a45d8dc..d9761c34e3 100644
> --- a/sysdeps/unix/sysv/linux/i386/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist
> index 93fcd64eee..f5dbb17ec9 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist
> @@ -6,3 +6,4 @@ GLIBC_2.36 __stack_chk_guard D 0x8
>  GLIBC_2.36 __tls_get_addr F
>  GLIBC_2.36 _dl_mcount F
>  GLIBC_2.36 _r_debug D 0x28
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
> index f1da2c636d..3d16fa60db 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.4 __stack_chk_guard D 0x4
>  GLIBC_2.4 __tls_get_addr F
>  GLIBC_2.4 _dl_mcount F
>  GLIBC_2.4 _r_debug D 0x14
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
> index dadbf852d0..3888e39812 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.4 __stack_chk_guard D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/microblaze/ld.abilist b/sysdeps/unix/sysv/linux/microblaze/ld.abilist
> index 89a0b7e4fd..c83b62dce7 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
> index e304d1bb46..9710fdb941 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.4 __stack_chk_guard D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
> index e304d1bb46..9710fdb941 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.4 __stack_chk_guard D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
> index f26e594a13..ec1bdfd965 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.4 __stack_chk_guard D 0x8
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/nios2/ld.abilist b/sysdeps/unix/sysv/linux/nios2/ld.abilist
> index 811ae9da2f..d2b742ec25 100644
> --- a/sysdeps/unix/sysv/linux/nios2/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/or1k/ld.abilist b/sysdeps/unix/sysv/linux/or1k/ld.abilist
> index cff2ffd23b..eb225ca4c5 100644
> --- a/sysdeps/unix/sysv/linux/or1k/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/or1k/ld.abilist
> @@ -6,3 +6,4 @@ GLIBC_2.35 __stack_chk_guard D 0x4
>  GLIBC_2.35 __tls_get_addr F
>  GLIBC_2.35 _dl_mcount F
>  GLIBC_2.35 _r_debug D 0x14
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
> index b1073f0942..7a94751723 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
> @@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
> index 40942a2cc6..f6bdd89083 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
> @@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
> index 01f2694a4d..672bade9ba 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
> @@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
> index 068368878e..d3be9236c2 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
> index a7758a0e52..46b22238ce 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
> index c15288394a..f438808c08 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
> @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
> index 78d071600b..f5fbc6de43 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
> @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sh/be/ld.abilist b/sysdeps/unix/sysv/linux/sh/be/ld.abilist
> index 7f5527fb30..8ae26c46c1 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.4 __stack_chk_guard D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sh/le/ld.abilist b/sysdeps/unix/sysv/linux/sh/le/ld.abilist
> index 7f5527fb30..8ae26c46c1 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/ld.abilist
> @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
>  GLIBC_2.4 __stack_chk_guard D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
> index 3aac73f3df..df3f7fefb3 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
> @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
> index 5471b24d59..3bf61e1210 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
> @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h
> index b8afab8945..a048ba8958 100644
> --- a/sysdeps/unix/sysv/linux/sys/rseq.h
> +++ b/sysdeps/unix/sysv/linux/sys/rseq.h
> @@ -163,6 +163,10 @@ extern const ptrdiff_t __rseq_offset;
>     unsuccessful.  */
>  extern const unsigned int __rseq_size;
>  
> +/* Size of the registered rseq features.  0 if the registration was
> +   unsuccessful.  */
> +extern const unsigned int __rseq_feature_size;

Ok.

> diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
> index ae4143916b..eb4b6278dc 100644
> --- a/sysdeps/unix/sysv/linux/tst-rseq-disable.c
> +++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
> @@ -39,6 +39,7 @@ check_rseq_disabled (void)
>  
>    TEST_COMPARE (__rseq_flags, 0);
>    TEST_COMPARE (__rseq_size, 0);
> +  TEST_COMPARE (__rseq_feature_size, 0);

Ok.

> diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c
> index c8c0518a5d..c5d9afbb0a 100644
> --- a/sysdeps/unix/sysv/linux/tst-rseq.c
> +++ b/sysdeps/unix/sysv/linux/tst-rseq.c
> @@ -38,12 +38,14 @@ static void
>  do_rseq_main_test (void)
>  {
>    size_t rseq_align = MAX (getauxval (AT_RSEQ_ALIGN), RSEQ_TEST_MIN_ALIGN);
> -  size_t rseq_size = roundup (MAX (getauxval (AT_RSEQ_FEATURE_SIZE), RSEQ_TEST_MIN_SIZE), rseq_align);
> +  size_t rseq_feature_size = MAX (getauxval (AT_RSEQ_FEATURE_SIZE), RSEQ_TEST_MIN_FEATURE_SIZE);
> +  size_t rseq_size = roundup (MAX (rseq_feature_size, RSEQ_TEST_MIN_SIZE), rseq_align);

Ok.

>    struct rseq *rseq = __thread_pointer () + __rseq_offset;
>  
>    TEST_VERIFY_EXIT (rseq_thread_registered ());
>    TEST_COMPARE (__rseq_flags, 0);
>    TEST_COMPARE (__rseq_size, rseq_size);
> +  TEST_COMPARE (__rseq_feature_size, rseq_feature_size);

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
> index 5a8bd322cd..25c2153c21 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
> @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x8
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
> index e17496d124..05327004e2 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
> @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F
>  GLIBC_2.35 __rseq_flags D 0x4
>  GLIBC_2.35 __rseq_offset D 0x4
>  GLIBC_2.35 __rseq_size D 0x4
> +GLIBC_2.40 __rseq_feature_size D 0x4

Ok.
Michael Jeanson Feb. 19, 2024, 7:25 p.m. UTC | #2
On 2024-02-16 17:07, DJ Delorie wrote:
> 
> * Suggestion for manual entry
> * attributes on externs
> * comment about _rseq_feature_size default
> 

>> diff --git a/manual/threads.texi b/manual/threads.texi
> 
>> +@deftypevar {unsigned int} __rseq_feature_size
>> +@standards{Linux, sys/rseq.h}
>> +This variable is either zero (if restartable sequence registration
>> +failed or has been disabled) or the size of the restartable sequence
>> +features.  If registration is successful, @code{__rseq_feature_size}
>> +is at least 20 (the initial feature size of @code{struct rseq}).
>> +@end deftypevar
> 
> Perhaps a note about where the magic value '20' comes from, and how to
> change it?  (Yes, *I* know it comes from the kernel, but the reader
> might not)

I'll add an explaination on where the magic value comes from.

Not sure about the 'change it' part, this minimum value is in the ABI and 
should never change. Do you mean explaining why the 'feature_size' would change?


>> diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
>> +extern unsigned int _rseq_feature_size attribute_relro attribute_hidden;
> 
> Again with attributes on externs.

Ack.


>> @@ -108,6 +109,7 @@ __tls_init_tp (void)
>>       if (rseq_register_current_thread (pd, do_rseq))
>>         {
>>           _rseq_size = GLRO (dl_tls_rseq_size);
>> +        _rseq_feature_size = GLRO (dl_tls_rseq_feature_size);
>>         }
> 
> Ok.  Note "comment needed here" from our other mail thread ;-)

Ack.
DJ Delorie Feb. 19, 2024, 7:43 p.m. UTC | #3
Michael Jeanson <mjeanson@efficios.com> writes:
> Not sure about the 'change it' part, this minimum value is in the ABI and 
> should never change. Do you mean explaining why the 'feature_size' would change?

Dunno, I'm not familiar enough with the kernel side of this.  *Is* it
something the user can change?  Does it depend on kernel versions?  Is
there some way of adding a user-specified region to this?

I was more worried about "magic numbers" than what they mean.

As for "it's ABI", the ABI used to have only 8 bytes in that struct ;-)
Michael Jeanson Feb. 19, 2024, 8:15 p.m. UTC | #4
On 2024-02-19 14:43, DJ Delorie wrote:
> Michael Jeanson <mjeanson@efficios.com> writes:
>> Not sure about the 'change it' part, this minimum value is in the ABI and
>> should never change. Do you mean explaining why the 'feature_size' would change?
> 
> Dunno, I'm not familiar enough with the kernel side of this.  *Is* it
> something the user can change?  Does it depend on kernel versions?  Is
> there some way of adding a user-specified region to this?
> 
> I was more worried about "magic numbers" than what they mean.
> 
> As for "it's ABI", the ABI used to have only 8 bytes in that struct ;-)

Ah ok I think I understand the confusion here.

The original implementation of rseq in linux v4.18 had a fixed size 'struct 
rseq' of 32 bytes and used 20 of those bytes, that's what we refer to as the 
'original ABI'.

In linux v6.3, the 'Extensible rseq ABI' was merged which added the feature 
size auxval and also added two 4 bytes fields, 'mm_cid' and 'node_id' bringing 
the feature size to 28.

Currently a call to getauxval should either return 0 or 28 until new features 
are added. If someone were to backport the feature size auxval to kernels 
between v4.18 and v6.3 it should return 20.

Thus access to any fields past 20 bytes have to be gated by a check of the 
feature size.

The initial glibc implementation of rseq used an internal 'struct rseq' of 8 
bytes because it only needed to access the first two fields of that structure.

Users have no control over those values, they entirely depend on the currently 
running kernel and the rseq features it implements.

That's why we floor the 'rseq_feature_size' to 20 when the auxval returns 0.

I hope this clarifies things, I'm unsure if this should be documented and if 
so, where?
DJ Delorie Feb. 19, 2024, 8:24 p.m. UTC | #5
Ok, I'm clarified :-)

Perhaps some wording that the number comes from the kernel?

> If registration is successful, @code{__rseq_feature_size} is at least
> 20 (the initial feature size of @code{struct rseq}).

becomes

> If registration is successful, @code{__rseq_feature_size} is as
> reported by the kernel, and is at least 20 (the smallest @code{struct
> rseq} the kernel has ever supported).

?

It removes any ambiguity about the origin of the number and if it's
something the user has local control over.

Or perhaps change

> or the size of the restartable sequence features.

To

> or the size of the restartable sequence features supported by the
> running kernel.

?
Michael Jeanson Feb. 19, 2024, 10:06 p.m. UTC | #6
On 2024-02-19 15:24, DJ Delorie wrote:
> 
> Ok, I'm clarified :-)
> 
> Perhaps some wording that the number comes from the kernel?
> 
>> If registration is successful, @code{__rseq_feature_size} is at least
>> 20 (the initial feature size of @code{struct rseq}).
> 
> becomes
> 
>> If registration is successful, @code{__rseq_feature_size} is as
>> reported by the kernel, and is at least 20 (the smallest @code{struct
>> rseq} the kernel has ever supported).
> 
> ?
> 
> It removes any ambiguity about the origin of the number and if it's
> something the user has local control over.
> 
> Or perhaps change
> 
>> or the size of the restartable sequence features.
> 
> To
> 
>> or the size of the restartable sequence features supported by the
>> running kernel.
> 
> ?

Would this make sense?

This variable is either zero (if restartable sequence registration
failed or has been disabled) or the size of the restartable sequence
features supported by the running kernel.  If registration is
successful, @code{__rseq_feature_size} is at least 20 (the feature size of 
@code{struct rseq} in the initial rseq kernel implementation).
DJ Delorie Feb. 19, 2024, 10:08 p.m. UTC | #7
Michael Jeanson <mjeanson@efficios.com> writes:
> Would this make sense?

Yup!

> This variable is either zero (if restartable sequence registration
> failed or has been disabled) or the size of the restartable sequence
> features supported by the running kernel.  If registration is
> successful, @code{__rseq_feature_size} is at least 20 (the feature size of 
> @code{struct rseq} in the initial rseq kernel implementation).
Michael Jeanson Feb. 19, 2024, 10:18 p.m. UTC | #8
On 2024-02-19 17:08, DJ Delorie wrote:
> Michael Jeanson <mjeanson@efficios.com> writes:
>> Would this make sense?
> 
> Yup!
> 
>> This variable is either zero (if restartable sequence registration
>> failed or has been disabled) or the size of the restartable sequence
>> features supported by the running kernel.  If registration is
>> successful, @code{__rseq_feature_size} is at least 20 (the feature size of
>> @code{struct rseq} in the initial rseq kernel implementation).
> 

Should I add a patch that does something similar for '__rseq_size'?
DJ Delorie Feb. 19, 2024, 10:21 p.m. UTC | #9
Michael Jeanson <mjeanson@efficios.com> writes:
>>> This variable is either zero (if restartable sequence registration
>>> failed or has been disabled) or the size of the restartable sequence
>>> features supported by the running kernel.  If registration is
>>> successful, @code{__rseq_feature_size} is at least 20 (the feature size of
>>> @code{struct rseq} in the initial rseq kernel implementation).
>> 
>
> Should I add a patch that does something similar for '__rseq_size'?

Sure.
diff mbox series

Patch

diff --git a/csu/rseq-sizes.sym b/csu/rseq-sizes.sym
index c959758ff0..dde53bfa60 100644
--- a/csu/rseq-sizes.sym
+++ b/csu/rseq-sizes.sym
@@ -4,5 +4,8 @@ 
 RSEQ_SIZE_SIZE		sizeof (unsigned int)
 RSEQ_SIZE_ALIGN		__alignof (unsigned int)
 
+RSEQ_FEATURE_SIZE_SIZE		sizeof (unsigned int)
+RSEQ_FEATURE_SIZE_ALIGN		__alignof (unsigned int)
+
 RSEQ_OFFSET_SIZE	sizeof (ptrdiff_t)
 RSEQ_OFFSET_ALIGN	__alignof (ptrdiff_t)
diff --git a/elf/dl-rseq-symbols.S b/elf/dl-rseq-symbols.S
index 2d8e88367f..709188ae22 100644
--- a/elf/dl-rseq-symbols.S
+++ b/elf/dl-rseq-symbols.S
@@ -38,6 +38,23 @@  __rseq_size:
 _rseq_size:
 	.zero	RSEQ_SIZE_SIZE
 
+/* Define 2 symbols, __rseq_feature_size is public const and
+   _rseq_feature_size, which is an alias of __rseq_feature_size, but hidden and
+   writable for internal use.  */
+
+	.globl	__rseq_feature_size
+	.type	__rseq_feature_size, %object
+	.size	__rseq_feature_size, RSEQ_FEATURE_SIZE_SIZE
+	.hidden _rseq_feature_size
+	.globl	_rseq_feature_size
+	.type	_rseq_feature_size, %object
+	.size	_rseq_feature_size, RSEQ_FEATURE_SIZE_SIZE
+	.section .data.rel.ro
+	.balign	RSEQ_FEATURE_SIZE_ALIGN
+__rseq_feature_size:
+_rseq_feature_size:
+	.zero	RSEQ_FEATURE_SIZE_SIZE
+
 /* Define 2 symbols, __rseq_offset is public const and _rseq_offset, which is an
    alias of __rseq_offset, but hidden and writable for internal use.  */
 
diff --git a/manual/threads.texi b/manual/threads.texi
index e5544ff3da..2c9aaa9fb5 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -1011,6 +1011,14 @@  registration is successful, @code{__rseq_size} is at least 32 (the
 initial size of @code{struct rseq}).
 @end deftypevar
 
+@deftypevar {unsigned int} __rseq_feature_size
+@standards{Linux, sys/rseq.h}
+This variable is either zero (if restartable sequence registration
+failed or has been disabled) or the size of the restartable sequence
+features.  If registration is successful, @code{__rseq_feature_size}
+is at least 20 (the initial feature size of @code{struct rseq}).
+@end deftypevar
+
 @deftypevar {unsigned int} __rseq_flags
 @standards{Linux, sys/rseq.h}
 The flags used during restartable sequence registration with the kernel.
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
index 7aa15558e6..8f19c22a74 100644
--- a/sysdeps/nptl/dl-tls_init_tp.c
+++ b/sysdeps/nptl/dl-tls_init_tp.c
@@ -48,6 +48,7 @@  const unsigned int __rseq_flags;
 
 /* The variables are in .data.relro but are not yet write-protected.  */
 extern unsigned int _rseq_size attribute_relro attribute_hidden;
+extern unsigned int _rseq_feature_size attribute_relro attribute_hidden;
 extern ptrdiff_t _rseq_offset attribute_relro attribute_hidden;
 
 void
@@ -108,6 +109,7 @@  __tls_init_tp (void)
     if (rseq_register_current_thread (pd, do_rseq))
       {
         _rseq_size = GLRO (dl_tls_rseq_size);
+        _rseq_feature_size = GLRO (dl_tls_rseq_feature_size);
       }
 
 #ifdef RSEQ_SIG
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 268ba1b6ac..055be26dde 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -356,6 +356,9 @@  ld {
     __rseq_offset;
     __rseq_size;
   }
+  GLIBC_2.40 {
+    __rseq_feature_size;
+  }
   GLIBC_PRIVATE {
     __nptl_change_stack_perm;
   }
diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
index 5151c0781d..93039b756d 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist
index 3e296c5473..fc67e31293 100644
--- a/sysdeps/unix/sysv/linux/alpha/ld.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.4 __stack_chk_guard D 0x8
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/arc/ld.abilist b/sysdeps/unix/sysv/linux/arc/ld.abilist
index 55f0c2ab9c..31156b6ee1 100644
--- a/sysdeps/unix/sysv/linux/arc/ld.abilist
+++ b/sysdeps/unix/sysv/linux/arc/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/arm/be/ld.abilist b/sysdeps/unix/sysv/linux/arm/be/ld.abilist
index f1da2c636d..3d16fa60db 100644
--- a/sysdeps/unix/sysv/linux/arm/be/ld.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.4 __stack_chk_guard D 0x4
 GLIBC_2.4 __tls_get_addr F
 GLIBC_2.4 _dl_mcount F
 GLIBC_2.4 _r_debug D 0x14
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/arm/le/ld.abilist b/sysdeps/unix/sysv/linux/arm/le/ld.abilist
index f1da2c636d..3d16fa60db 100644
--- a/sysdeps/unix/sysv/linux/arm/le/ld.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.4 __stack_chk_guard D 0x4
 GLIBC_2.4 __tls_get_addr F
 GLIBC_2.4 _dl_mcount F
 GLIBC_2.4 _r_debug D 0x14
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/csky/ld.abilist b/sysdeps/unix/sysv/linux/csky/ld.abilist
index 7f482276ed..088f000c4e 100644
--- a/sysdeps/unix/sysv/linux/csky/ld.abilist
+++ b/sysdeps/unix/sysv/linux/csky/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/hppa/ld.abilist b/sysdeps/unix/sysv/linux/hppa/ld.abilist
index 7f5527fb30..8ae26c46c1 100644
--- a/sysdeps/unix/sysv/linux/hppa/ld.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.4 __stack_chk_guard D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist
index 9c4a45d8dc..d9761c34e3 100644
--- a/sysdeps/unix/sysv/linux/i386/ld.abilist
+++ b/sysdeps/unix/sysv/linux/i386/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist
index 93fcd64eee..f5dbb17ec9 100644
--- a/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist
@@ -6,3 +6,4 @@  GLIBC_2.36 __stack_chk_guard D 0x8
 GLIBC_2.36 __tls_get_addr F
 GLIBC_2.36 _dl_mcount F
 GLIBC_2.36 _r_debug D 0x28
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
index f1da2c636d..3d16fa60db 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.4 __stack_chk_guard D 0x4
 GLIBC_2.4 __tls_get_addr F
 GLIBC_2.4 _dl_mcount F
 GLIBC_2.4 _r_debug D 0x14
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
index dadbf852d0..3888e39812 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.4 __stack_chk_guard D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/microblaze/ld.abilist b/sysdeps/unix/sysv/linux/microblaze/ld.abilist
index 89a0b7e4fd..c83b62dce7 100644
--- a/sysdeps/unix/sysv/linux/microblaze/ld.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
index e304d1bb46..9710fdb941 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.4 __stack_chk_guard D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
index e304d1bb46..9710fdb941 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.4 __stack_chk_guard D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
index f26e594a13..ec1bdfd965 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.4 __stack_chk_guard D 0x8
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/nios2/ld.abilist b/sysdeps/unix/sysv/linux/nios2/ld.abilist
index 811ae9da2f..d2b742ec25 100644
--- a/sysdeps/unix/sysv/linux/nios2/ld.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/or1k/ld.abilist b/sysdeps/unix/sysv/linux/or1k/ld.abilist
index cff2ffd23b..eb225ca4c5 100644
--- a/sysdeps/unix/sysv/linux/or1k/ld.abilist
+++ b/sysdeps/unix/sysv/linux/or1k/ld.abilist
@@ -6,3 +6,4 @@  GLIBC_2.35 __stack_chk_guard D 0x4
 GLIBC_2.35 __tls_get_addr F
 GLIBC_2.35 _dl_mcount F
 GLIBC_2.35 _r_debug D 0x14
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
index b1073f0942..7a94751723 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
@@ -9,3 +9,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
index 40942a2cc6..f6bdd89083 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
@@ -9,3 +9,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
index 01f2694a4d..672bade9ba 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
@@ -9,3 +9,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
index 068368878e..d3be9236c2 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
index a7758a0e52..46b22238ce 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
index c15288394a..f438808c08 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
@@ -6,3 +6,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
index 78d071600b..f5fbc6de43 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
@@ -6,3 +6,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/sh/be/ld.abilist b/sysdeps/unix/sysv/linux/sh/be/ld.abilist
index 7f5527fb30..8ae26c46c1 100644
--- a/sysdeps/unix/sysv/linux/sh/be/ld.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.4 __stack_chk_guard D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/sh/le/ld.abilist b/sysdeps/unix/sysv/linux/sh/le/ld.abilist
index 7f5527fb30..8ae26c46c1 100644
--- a/sysdeps/unix/sysv/linux/sh/le/ld.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/ld.abilist
@@ -7,3 +7,4 @@  GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
 GLIBC_2.4 __stack_chk_guard D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
index 3aac73f3df..df3f7fefb3 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
@@ -6,3 +6,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
index 5471b24d59..3bf61e1210 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
@@ -6,3 +6,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h
index b8afab8945..a048ba8958 100644
--- a/sysdeps/unix/sysv/linux/sys/rseq.h
+++ b/sysdeps/unix/sysv/linux/sys/rseq.h
@@ -163,6 +163,10 @@  extern const ptrdiff_t __rseq_offset;
    unsuccessful.  */
 extern const unsigned int __rseq_size;
 
+/* Size of the registered rseq features.  0 if the registration was
+   unsuccessful.  */
+extern const unsigned int __rseq_feature_size;
+
 /* Flags used during rseq registration.  */
 extern const unsigned int __rseq_flags;
 
diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
index ae4143916b..eb4b6278dc 100644
--- a/sysdeps/unix/sysv/linux/tst-rseq-disable.c
+++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
@@ -39,6 +39,7 @@  check_rseq_disabled (void)
 
   TEST_COMPARE (__rseq_flags, 0);
   TEST_COMPARE (__rseq_size, 0);
+  TEST_COMPARE (__rseq_feature_size, 0);
   TEST_COMPARE ((int) rseq_area->cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
 
   TEST_COMPARE (sizeof (local_rseq), RSEQ_TEST_MIN_SIZE);
diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c
index c8c0518a5d..c5d9afbb0a 100644
--- a/sysdeps/unix/sysv/linux/tst-rseq.c
+++ b/sysdeps/unix/sysv/linux/tst-rseq.c
@@ -38,12 +38,14 @@  static void
 do_rseq_main_test (void)
 {
   size_t rseq_align = MAX (getauxval (AT_RSEQ_ALIGN), RSEQ_TEST_MIN_ALIGN);
-  size_t rseq_size = roundup (MAX (getauxval (AT_RSEQ_FEATURE_SIZE), RSEQ_TEST_MIN_SIZE), rseq_align);
+  size_t rseq_feature_size = MAX (getauxval (AT_RSEQ_FEATURE_SIZE), RSEQ_TEST_MIN_FEATURE_SIZE);
+  size_t rseq_size = roundup (MAX (rseq_feature_size, RSEQ_TEST_MIN_SIZE), rseq_align);
   struct rseq *rseq = __thread_pointer () + __rseq_offset;
 
   TEST_VERIFY_EXIT (rseq_thread_registered ());
   TEST_COMPARE (__rseq_flags, 0);
   TEST_COMPARE (__rseq_size, rseq_size);
+  TEST_COMPARE (__rseq_feature_size, rseq_feature_size);
   /* The size of the rseq area must be a multiple of the alignment.  */
   TEST_VERIFY ((__rseq_size % rseq_align) == 0);
   /* The rseq area address must be aligned.  */
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
index 5a8bd322cd..25c2153c21 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
@@ -6,3 +6,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x8
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
index e17496d124..05327004e2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
@@ -6,3 +6,4 @@  GLIBC_2.34 __rtld_version_placeholder F
 GLIBC_2.35 __rseq_flags D 0x4
 GLIBC_2.35 __rseq_offset D 0x4
 GLIBC_2.35 __rseq_size D 0x4
+GLIBC_2.40 __rseq_feature_size D 0x4