aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/sys')
-rw-r--r--sysdeps/unix/sysv/linux/sys/rseq.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h
new file mode 100644
index 0000000000..c8edff50d4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sys/rseq.h
@@ -0,0 +1,174 @@
+/* Restartable Sequences exported symbols. Linux header.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_RSEQ_H
+#define _SYS_RSEQ_H 1
+
+/* Architecture-specific rseq signature. */
+#include <bits/rseq.h>
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <bits/endian.h>
+
+#ifdef __has_include
+# if __has_include ("linux/rseq.h")
+# define __GLIBC_HAVE_KERNEL_RSEQ
+# endif
+#else
+# include <linux/version.h>
+# if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 18, 0)
+# define __GLIBC_HAVE_KERNEL_RSEQ
+# endif
+#endif
+
+#ifdef __GLIBC_HAVE_KERNEL_RSEQ
+/* We use the structures declarations from the kernel headers. */
+# include <linux/rseq.h>
+#else /* __GLIBC_HAVE_KERNEL_RSEQ */
+/* We use a copy of the include/uapi/linux/rseq.h kernel header. */
+
+enum rseq_cpu_id_state
+ {
+ RSEQ_CPU_ID_UNINITIALIZED = -1,
+ RSEQ_CPU_ID_REGISTRATION_FAILED = -2,
+ };
+
+enum rseq_flags
+ {
+ RSEQ_FLAG_UNREGISTER = (1 << 0),
+ };
+
+enum rseq_cs_flags_bit
+ {
+ RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0,
+ RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1,
+ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2,
+ };
+
+enum rseq_cs_flags
+ {
+ RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT =
+ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT),
+ RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL =
+ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT),
+ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE =
+ (1U << RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT),
+ };
+
+/* struct rseq_cs is aligned on 32 bytes to ensure it is always
+ contained within a single cache-line. It is usually declared as
+ link-time constant data. */
+struct rseq_cs
+ {
+ /* Version of this structure. */
+ uint32_t version;
+ /* enum rseq_cs_flags. */
+ uint32_t flags;
+ uint64_t start_ip;
+ /* Offset from start_ip. */
+ uint64_t post_commit_offset;
+ uint64_t abort_ip;
+ } __attribute__ ((__aligned__ (32)));
+
+/* struct rseq is aligned on 32 bytes to ensure it is always
+ contained within a single cache-line.
+
+ A single struct rseq per thread is allowed. */
+struct rseq
+ {
+ /* Restartable sequences cpu_id_start field. Updated by the
+ kernel. Read by user-space with single-copy atomicity
+ semantics. This field should only be read by the thread which
+ registered this data structure. Aligned on 32-bit. Always
+ contains a value in the range of possible CPUs, although the
+ value may not be the actual current CPU (e.g. if rseq is not
+ initialized). This CPU number value should always be compared
+ against the value of the cpu_id field before performing a rseq
+ commit or returning a value read from a data structure indexed
+ using the cpu_id_start value. */
+ uint32_t cpu_id_start;
+ /* Restartable sequences cpu_id field. Updated by the kernel.
+ Read by user-space with single-copy atomicity semantics. This
+ field should only be read by the thread which registered this
+ data structure. Aligned on 32-bit. Values
+ RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED
+ have a special semantic: the former means "rseq uninitialized",
+ and latter means "rseq initialization failed". This value is
+ meant to be read within rseq critical sections and compared
+ with the cpu_id_start value previously read, before performing
+ the commit instruction, or read and compared with the
+ cpu_id_start value before returning a value loaded from a data
+ structure indexed using the cpu_id_start value. */
+ uint32_t cpu_id;
+ /* Restartable sequences rseq_cs field.
+
+ Contains NULL when no critical section is active for the current
+ thread, or holds a pointer to the currently active struct rseq_cs.
+
+ Updated by user-space, which sets the address of the currently
+ active rseq_cs at the beginning of assembly instruction sequence
+ block, and set to NULL by the kernel when it restarts an assembly
+ instruction sequence block, as well as when the kernel detects that
+ it is preempting or delivering a signal outside of the range
+ targeted by the rseq_cs. Also needs to be set to NULL by user-space
+ before reclaiming memory that contains the targeted struct rseq_cs.
+
+ Read and set by the kernel. Set by user-space with single-copy
+ atomicity semantics. This field should only be updated by the
+ thread which registered this data structure. Aligned on 64-bit. */
+ union
+ {
+ uint64_t ptr64;
+# ifdef __LP64__
+ uint64_t ptr;
+# else /* __LP64__ */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ uint32_t padding; /* Initialized to zero. */
+ uint32_t ptr32;
+# else /* LITTLE */
+ uint32_t ptr32;
+ uint32_t padding; /* Initialized to zero. */
+# endif /* ENDIAN */
+ } ptr;
+# endif /* __LP64__ */
+ } rseq_cs;
+
+ /* Restartable sequences flags field.
+
+ This field should only be updated by the thread which
+ registered this data structure. Read by the kernel.
+ Mainly used for single-stepping through rseq critical sections
+ with debuggers.
+
+ - RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT
+ Inhibit instruction sequence block restart on preemption
+ for this thread.
+ - RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL
+ Inhibit instruction sequence block restart on signal
+ delivery for this thread.
+ - RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE
+ Inhibit instruction sequence block restart on migration for
+ this thread. */
+ uint32_t flags;
+ } __attribute__ ((__aligned__ (32)));
+
+#endif /* __GLIBC_HAVE_KERNEL_RSEQ */
+
+#endif /* sys/rseq.h */