|
|
@@ -10,13 +10,8 @@
|
|
|
* Copyright (c) 2015-2018 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
|
|
*/
|
|
|
|
|
|
-#ifdef __KERNEL__
|
|
|
-# include <linux/types.h>
|
|
|
-#else
|
|
|
-# include <stdint.h>
|
|
|
-#endif
|
|
|
-
|
|
|
-#include <linux/types_32_64.h>
|
|
|
+#include <linux/types.h>
|
|
|
+#include <asm/byteorder.h>
|
|
|
|
|
|
enum rseq_cpu_id_state {
|
|
|
RSEQ_CPU_ID_UNINITIALIZED = -1,
|
|
|
@@ -52,10 +47,10 @@ struct rseq_cs {
|
|
|
__u32 version;
|
|
|
/* enum rseq_cs_flags */
|
|
|
__u32 flags;
|
|
|
- LINUX_FIELD_u32_u64(start_ip);
|
|
|
+ __u64 start_ip;
|
|
|
/* Offset from start_ip. */
|
|
|
- LINUX_FIELD_u32_u64(post_commit_offset);
|
|
|
- LINUX_FIELD_u32_u64(abort_ip);
|
|
|
+ __u64 post_commit_offset;
|
|
|
+ __u64 abort_ip;
|
|
|
} __attribute__((aligned(4 * sizeof(__u64))));
|
|
|
|
|
|
/*
|
|
|
@@ -67,28 +62,30 @@ struct rseq_cs {
|
|
|
struct rseq {
|
|
|
/*
|
|
|
* Restartable sequences cpu_id_start field. Updated by the
|
|
|
- * kernel, and read by user-space with single-copy atomicity
|
|
|
- * semantics. 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.
|
|
|
+ * 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,
|
|
|
- * and read by user-space with single-copy atomicity semantics.
|
|
|
- * 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.
|
|
|
+ * 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;
|
|
|
/*
|
|
|
@@ -105,27 +102,44 @@ struct rseq {
|
|
|
* 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 with single-copy atomicity semantics.
|
|
|
- * Set by user-space with single-copy atomicity semantics. Aligned
|
|
|
- * on 64-bit.
|
|
|
+ * 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.
|
|
|
*/
|
|
|
- LINUX_FIELD_u32_u64(rseq_cs);
|
|
|
+ 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;
|
|
|
+
|
|
|
/*
|
|
|
- * - RSEQ_DISABLE flag:
|
|
|
+ * 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.
|
|
|
*
|
|
|
- * Fallback fast-track flag for single-stepping.
|
|
|
- * Set by user-space if lack of progress is detected.
|
|
|
- * Cleared by user-space after rseq finish.
|
|
|
- * Read by the kernel.
|
|
|
* - RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT
|
|
|
- * Inhibit instruction sequence block restart and event
|
|
|
- * counter increment on preemption for this thread.
|
|
|
+ * Inhibit instruction sequence block restart on preemption
|
|
|
+ * for this thread.
|
|
|
* - RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL
|
|
|
- * Inhibit instruction sequence block restart and event
|
|
|
- * counter increment on signal delivery for this thread.
|
|
|
+ * Inhibit instruction sequence block restart on signal
|
|
|
+ * delivery for this thread.
|
|
|
* - RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE
|
|
|
- * Inhibit instruction sequence block restart and event
|
|
|
- * counter increment on migration for this thread.
|
|
|
+ * Inhibit instruction sequence block restart on migration for
|
|
|
+ * this thread.
|
|
|
*/
|
|
|
__u32 flags;
|
|
|
} __attribute__((aligned(4 * sizeof(__u64))));
|