+++ /dev/null
-Kernel headers for test builds. Do not use for production builds.
-
-- linux/rseq.h
-
- It is a copy from the upstream Linux v5.0 kernel uapi.
-
- It also contains definitive system call number definitions for the rseq
- system call, in case the kernel uapi headers are not recent enough
- to define them.
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
-#ifndef _UAPI_LINUX_RSEQ_H
-#define _UAPI_LINUX_RSEQ_H
-
-/*
- * linux/rseq.h
- *
- * Restartable sequences system call API
- *
- * Copyright (c) 2015-2018 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-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 4 * 8 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. */
- __u32 version;
- /* enum rseq_cs_flags */
- __u32 flags;
- __u64 start_ip;
- /* Offset from start_ip. */
- __u64 post_commit_offset;
- __u64 abort_ip;
-} __attribute__((aligned(4 * sizeof(__u64))));
-
-/*
- * struct rseq is aligned on 4 * 8 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.
- */
- __u32 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.
- */
- __u32 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 {
- __u64 ptr64;
-#ifdef __LP64__
- __u64 ptr;
-#else
- struct {
-#if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || defined(__BIG_ENDIAN)
- __u32 padding; /* Initialized to zero. */
- __u32 ptr32;
-#else /* LITTLE */
- __u32 ptr32;
- __u32 padding; /* Initialized to zero. */
-#endif /* ENDIAN */
- } ptr;
-#endif
- } 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.
- */
- __u32 flags;
-} __attribute__((aligned(4 * sizeof(__u64))));
-
-/*
- * Define the rseq system call number if not yet available in
- * the system headers.
- */
-#ifdef __x86_64__
-
-#ifndef __NR_rseq
-#define __NR_rseq 334
-#endif
-
-#elif defined(__i386__)
-
-#ifndef __NR_rseq
-#define __NR_rseq 386
-#endif
-
-#elif defined(__AARCH64EL__)
-
-#ifndef __NR_rseq
-#define __NR_rseq 293
-#endif
-
-#elif defined(__ARMEL__)
-
-#ifndef __NR_rseq
-#define __NR_rseq 398
-#endif
-
-#elif defined(__PPC__)
-
-#ifndef __NR_rseq
-#define __NR_rseq 387
-#endif
-
-#elif defined(__s390__)
-
-#ifndef __NR_rseq
-#define __NR_rseq 383
-#endif
-
-#endif
-
-#endif /* _UAPI_LINUX_RSEQ_H */
nobase_include_HEADERS = \
rseq/compiler.h \
rseq/rseq.h \
+ rseq/rseq-abi.h \
rseq/rseq-arm.h \
rseq/rseq-mips.h \
rseq/rseq-ppc.h \
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+#ifndef _RSEQ_ABI_H
+#define _RSEQ_ABI_H
+
+/*
+ * rseq/rseq-abi.h
+ *
+ * Restartable sequences system call API
+ *
+ * Copyright (c) 2015-2018 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+enum rseq_abi_cpu_id_state {
+ RSEQ_ABI_CPU_ID_UNINITIALIZED = -1,
+ RSEQ_ABI_CPU_ID_REGISTRATION_FAILED = -2,
+};
+
+enum rseq_abi_flags {
+ RSEQ_ABI_FLAG_UNREGISTER = (1 << 0),
+};
+
+enum rseq_abi_cs_flags_bit {
+ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0,
+ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1,
+ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2,
+};
+
+enum rseq_abi_cs_flags {
+ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT =
+ (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT),
+ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL =
+ (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT),
+ RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE =
+ (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT),
+};
+
+/*
+ * struct rseq_abi_cs is aligned on 4 * 8 bytes to ensure it is always
+ * contained within a single cache-line. It is usually declared as
+ * link-time constant data.
+ */
+struct rseq_abi_cs {
+ /* Version of this structure. */
+ __u32 version;
+ /* enum rseq_abi_cs_flags */
+ __u32 flags;
+ __u64 start_ip;
+ /* Offset from start_ip. */
+ __u64 post_commit_offset;
+ __u64 abort_ip;
+} __attribute__((aligned(4 * sizeof(__u64))));
+
+/*
+ * struct rseq_abi is aligned on 4 * 8 bytes to ensure it is always
+ * contained within a single cache-line.
+ *
+ * A single struct rseq_abi per thread is allowed.
+ */
+struct rseq_abi {
+ /*
+ * 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.
+ */
+ __u32 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.
+ */
+ __u32 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 {
+ __u64 ptr64;
+
+ /*
+ * The "arch" field provides architecture accessor for
+ * the ptr field based on architecture pointer size and
+ * endianness.
+ */
+ struct {
+#ifdef __LP64__
+ __u64 ptr;
+#elif defined(__BYTE_ORDER) ? (__BYTE_ORDER == __BIG_ENDIAN) : defined(__BIG_ENDIAN)
+ __u32 padding; /* Initialized to zero. */
+ __u32 ptr;
+#else
+ __u32 ptr;
+ __u32 padding; /* Initialized to zero. */
+#endif
+ } arch;
+ } 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_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT
+ * Inhibit instruction sequence block restart on preemption
+ * for this thread.
+ * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL
+ * Inhibit instruction sequence block restart on signal
+ * delivery for this thread.
+ * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE
+ * Inhibit instruction sequence block restart on migration for
+ * this thread.
+ */
+ __u32 flags;
+} __attribute__((aligned(4 * sizeof(__u64))));
+
+/*
+ * Define the rseq system call number if not yet available in
+ * the system headers.
+ */
+#ifdef __x86_64__
+
+#ifndef __NR_rseq
+#define __NR_rseq 334
+#endif
+
+#elif defined(__i386__)
+
+#ifndef __NR_rseq
+#define __NR_rseq 386
+#endif
+
+#elif defined(__AARCH64EL__)
+
+#ifndef __NR_rseq
+#define __NR_rseq 293
+#endif
+
+#elif defined(__ARMEL__)
+
+#ifndef __NR_rseq
+#define __NR_rseq 398
+#endif
+
+#elif defined(__PPC__)
+
+#ifndef __NR_rseq
+#define __NR_rseq 387
+#endif
+
+#elif defined(__s390__)
+
+#ifndef __NR_rseq
+#define __NR_rseq 383
+#endif
+
+#endif
+
+#endif /* _RSEQ_ABI_H */
#define RSEQ_SIG 0xe7f5def3 /* udf #24035 ; 0x5de3 */
#endif
-#define RSEQ_CS_PTR RSEQ_CS_PTR32
-
#define rseq_smp_mb() __asm__ __volatile__ ("dmb" ::: "memory", "cc")
#define rseq_smp_rmb() __asm__ __volatile__ ("dmb" ::: "memory", "cc")
#define rseq_smp_wmb() __asm__ __volatile__ ("dmb" ::: "memory", "cc")
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "m" (*v),
[expect] "r" (expect),
[newv] "r" (newv)
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expectnot] "r" (expectnot),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "m" (*v),
[count] "Ir" (count)
RSEQ_INJECT_INPUT
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* try store input */
[v2] "m" (*v2),
[newv2] "r" (newv2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* try store input */
[v2] "m" (*v2),
[newv2] "r" (newv2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* cmp2 input */
[v2] "m" (*v2),
[expect2] "r" (expect2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expect] "r" (expect),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expect] "r" (expect),
#define RSEQ_SIG RSEQ_SIG_DATA
-#define RSEQ_CS_PTR rseq_cs.ptr
-
#define rseq_smp_mb() __asm__ __volatile__ ("dmb ish" ::: "memory")
#define rseq_smp_rmb() __asm__ __volatile__ ("dmb ishld" ::: "memory")
#define rseq_smp_wmb() __asm__ __volatile__ ("dmb ishst" ::: "memory")
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "Qo" (*v),
[expect] "r" (expect),
[newv] "r" (newv)
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "Qo" (*v),
[expectnot] "r" (expectnot),
[load] "Qo" (*load),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "Qo" (*v),
[count] "r" (count)
RSEQ_INJECT_INPUT
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[expect] "r" (expect),
[v] "Qo" (*v),
[newv] "r" (newv),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[expect] "r" (expect),
[v] "Qo" (*v),
[newv] "r" (newv),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "Qo" (*v),
[expect] "r" (expect),
[v2] "Qo" (*v2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[expect] "r" (expect),
[v] "Qo" (*v),
[newv] "r" (newv),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "Qo" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[expect] "r" (expect),
[v] "Qo" (*v),
[newv] "r" (newv),
# define LONG_S "sd"
# define LONG_ADDI "daddiu"
# define U32_U64_PAD(x) x
-# define RSEQ_CS_PTR rseq_cs.ptr
#elif _MIPS_SZLONG == 32
# define LONG ".word"
# define LONG_LA "la"
# else
# define U32_U64_PAD(x) x ", 0x0"
# endif
-# define RSEQ_CS_PTR RSEQ_CS_PTR32
#else
# error unsupported _MIPS_SZLONG
#endif
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "m" (*v),
[expect] "r" (expect),
[newv] "r" (newv)
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expectnot] "r" (expectnot),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "m" (*v),
[count] "Ir" (count)
RSEQ_INJECT_INPUT
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* try store input */
[v2] "m" (*v2),
[newv2] "r" (newv2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* try store input */
[v2] "m" (*v2),
[newv2] "r" (newv2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* cmp2 input */
[v2] "m" (*v2),
[expect2] "r" (expect2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expect] "r" (expect),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expect] "r" (expect),
#define RSEQ_CMP_LONG "cmpd "
#define RSEQ_CMP_LONG_INT "cmpdi "
-#define RSEQ_CS_PTR rseq_cs.ptr
-
#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
start_ip, post_commit_offset, abort_ip) \
".pushsection __rseq_cs, \"aw\"\n\t" \
#define RSEQ_CMP_LONG "cmpw "
#define RSEQ_CMP_LONG_INT "cmpwi "
-#define RSEQ_CS_PTR RSEQ_CS_PTR32
-
#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
start_ip, post_commit_offset, abort_ip) \
".pushsection __rseq_cs, \"aw\"\n\t" \
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "m" (*v),
[expect] "r" (expect),
[newv] "r" (newv)
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expectnot] "r" (expectnot),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[count] "r" (count)
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* try store input */
[v2] "m" (*v2),
[newv2] "r" (newv2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* try store input */
[v2] "m" (*v2),
[newv2] "r" (newv2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* cmp2 input */
[v2] "m" (*v2),
[expect2] "r" (expect2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expect] "r" (expect),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expect] "r" (expect),
#ifdef __s390x__
-#define RSEQ_CS_PTR rseq_cs.ptr
-
#define LONG_L "lg"
#define LONG_S "stg"
#define LONG_LT_R "ltgr"
#elif __s390__
-#define RSEQ_CS_PTR RSEQ_CS_PTR32
-
#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
start_ip, post_commit_offset, abort_ip) \
".pushsection __rseq_cs, \"aw\"\n\t" \
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
[v] "m" (*v),
[expect] "r" (expect),
[newv] "r" (newv)
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expectnot] "r" (expectnot),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[count] "r" (count)
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* try store input */
[v2] "m" (*v2),
[newv2] "r" (newv2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* cmp2 input */
[v2] "m" (*v2),
[expect2] "r" (expect2),
: /* gcc asm goto does not allow outputs */
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_get_abi()->cpu_id),
- [rseq_cs] "m" (rseq_get_abi()->RSEQ_CS_PTR),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
/* final store input */
[v] "m" (*v),
[expect] "r" (expect),
* (TODO: revisit after migration to glibc's ABI)
*/
-/* Offset of cpu_id and rseq_cs fields in struct rseq. */
+/* Offset of cpu_id and rseq_cs fields in struct rseq_abi. */
#define RSEQ_CPU_ID_OFFSET 4
#define RSEQ_CS_OFFSET 8
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
-#include <linux/rseq.h>
+#include <rseq/rseq-abi.h>
#include <rseq/compiler.h>
-/* Work-around rseq.h uapi bug wrt endianness on little endian. */
-#if !(defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN))
-# if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || defined(__BIG_ENDIAN)
-/* Kernel uapi mistakenly orders padding vs ptr32. */
-# define RSEQ_CS_PTR32 rseq_cs.ptr.padding
-# endif
-#endif
-
-#ifndef RSEQ_CS_PTR32
-# define RSEQ_CS_PTR32 rseq_cs.ptr.ptr32
-#endif
-
/*
* Empty code injection macros, override when testing.
* It is important to consider that the ASM injection macros need to be
/* Flags used during rseq registration. */
extern unsigned int rseq_flags;
-static inline struct rseq *rseq_get_abi(void)
+static inline struct rseq_abi *rseq_get_abi(void)
{
- return (struct rseq *) ((uintptr_t) rseq_thread_pointer() + rseq_offset);
+ return (struct rseq_abi *) ((uintptr_t) rseq_thread_pointer() + rseq_offset);
}
# ifdef __cplusplus
static inline void rseq_clear_rseq_cs(void)
{
-#ifdef __LP64__
- RSEQ_WRITE_ONCE(rseq_get_abi()->rseq_cs.ptr, 0);
-#else
- RSEQ_WRITE_ONCE(rseq_get_abi()->RSEQ_CS_PTR32, 0);
-#endif
+ RSEQ_WRITE_ONCE(rseq_get_abi()->rseq_cs.arch.ptr, 0);
}
/*
* rseq_prepare_unload() should be invoked by each thread executing a rseq
* critical section at least once between their last critical section and
* library unload of the library defining the rseq critical section
- * (struct rseq_cs). This also applies to use of rseq in code generated by
+ * (struct rseq_ab_cs). This also applies to use of rseq in code generated by
* JIT: rseq_prepare_unload() should be invoked at least once by each
* thread executing a rseq critical section before reclaim of the memory
- * holding the struct rseq_cs.
+ * holding the struct rseq_abi_cs.
*/
static inline void rseq_prepare_unload(void)
{
static int rseq_ownership;
static
-__thread struct rseq __rseq_abi __attribute__((tls_model("initial-exec"))) = {
- .cpu_id = RSEQ_CPU_ID_UNINITIALIZED,
+__thread struct rseq_abi __rseq_abi __attribute__((tls_model("initial-exec"))) = {
+ .cpu_id = RSEQ_ABI_CPU_ID_UNINITIALIZED,
};
-static int sys_rseq(struct rseq *rseq_abi, uint32_t rseq_len,
+static int sys_rseq(struct rseq_abi *rseq_abi, uint32_t rseq_len,
int flags, uint32_t sig)
{
return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig);
/* Treat libc's ownership as a successful registration. */
return 0;
}
- rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 0, RSEQ_SIG);
+ rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), 0, RSEQ_SIG);
if (rc)
return -1;
assert(rseq_current_cpu_raw() >= 0);
/* Treat libc's ownership as a successful unregistration. */
return 0;
}
- rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
+ rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG);
if (rc)
return -1;
return 0;
return;
rseq_ownership = 1;
rseq_offset = (void *)&__rseq_abi - rseq_thread_pointer();
- rseq_size = sizeof(struct rseq);
+ rseq_size = sizeof(struct rseq_abi);
rseq_flags = 0;
}