1/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
2#ifndef _RSEQ_ABI_H
3#define _RSEQ_ABI_H
4
5/*
6 * rseq-abi.h
7 *
8 * Restartable sequences system call API
9 *
10 * Copyright (c) 2015-2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
11 */
12
13#include <linux/types.h>
14#include <asm/byteorder.h>
15
16enum rseq_abi_cpu_id_state {
17	RSEQ_ABI_CPU_ID_UNINITIALIZED			= -1,
18	RSEQ_ABI_CPU_ID_REGISTRATION_FAILED		= -2,
19};
20
21enum rseq_abi_flags {
22	RSEQ_ABI_FLAG_UNREGISTER = (1 << 0),
23};
24
25enum rseq_abi_cs_flags_bit {
26	RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT	= 0,
27	RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT	= 1,
28	RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT	= 2,
29};
30
31enum rseq_abi_cs_flags {
32	RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT	=
33		(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT),
34	RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL	=
35		(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT),
36	RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE	=
37		(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT),
38};
39
40/*
41 * struct rseq_abi_cs is aligned on 4 * 8 bytes to ensure it is always
42 * contained within a single cache-line. It is usually declared as
43 * link-time constant data.
44 */
45struct rseq_abi_cs {
46	/* Version of this structure. */
47	__u32 version;
48	/* enum rseq_abi_cs_flags */
49	__u32 flags;
50	__u64 start_ip;
51	/* Offset from start_ip. */
52	__u64 post_commit_offset;
53	__u64 abort_ip;
54} __attribute__((aligned(4 * sizeof(__u64))));
55
56/*
57 * struct rseq_abi is aligned on 4 * 8 bytes to ensure it is always
58 * contained within a single cache-line.
59 *
60 * A single struct rseq_abi per thread is allowed.
61 */
62struct rseq_abi {
63	/*
64	 * Restartable sequences cpu_id_start field. Updated by the
65	 * kernel. Read by user-space with single-copy atomicity
66	 * semantics. This field should only be read by the thread which
67	 * registered this data structure. Aligned on 32-bit. Always
68	 * contains a value in the range of possible CPUs, although the
69	 * value may not be the actual current CPU (e.g. if rseq is not
70	 * initialized). This CPU number value should always be compared
71	 * against the value of the cpu_id field before performing a rseq
72	 * commit or returning a value read from a data structure indexed
73	 * using the cpu_id_start value.
74	 */
75	__u32 cpu_id_start;
76	/*
77	 * Restartable sequences cpu_id field. Updated by the kernel.
78	 * Read by user-space with single-copy atomicity semantics. This
79	 * field should only be read by the thread which registered this
80	 * data structure. Aligned on 32-bit. Values
81	 * RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED
82	 * have a special semantic: the former means "rseq uninitialized",
83	 * and latter means "rseq initialization failed". This value is
84	 * meant to be read within rseq critical sections and compared
85	 * with the cpu_id_start value previously read, before performing
86	 * the commit instruction, or read and compared with the
87	 * cpu_id_start value before returning a value loaded from a data
88	 * structure indexed using the cpu_id_start value.
89	 */
90	__u32 cpu_id;
91	/*
92	 * Restartable sequences rseq_cs field.
93	 *
94	 * Contains NULL when no critical section is active for the current
95	 * thread, or holds a pointer to the currently active struct rseq_cs.
96	 *
97	 * Updated by user-space, which sets the address of the currently
98	 * active rseq_cs at the beginning of assembly instruction sequence
99	 * block, and set to NULL by the kernel when it restarts an assembly
100	 * instruction sequence block, as well as when the kernel detects that
101	 * it is preempting or delivering a signal outside of the range
102	 * targeted by the rseq_cs. Also needs to be set to NULL by user-space
103	 * before reclaiming memory that contains the targeted struct rseq_cs.
104	 *
105	 * Read and set by the kernel. Set by user-space with single-copy
106	 * atomicity semantics. This field should only be updated by the
107	 * thread which registered this data structure. Aligned on 64-bit.
108	 */
109	union {
110		__u64 ptr64;
111
112		/*
113		 * The "arch" field provides architecture accessor for
114		 * the ptr field based on architecture pointer size and
115		 * endianness.
116		 */
117		struct {
118#ifdef __LP64__
119			__u64 ptr;
120#elif defined(__BYTE_ORDER) ? (__BYTE_ORDER == __BIG_ENDIAN) : defined(__BIG_ENDIAN)
121			__u32 padding;		/* Initialized to zero. */
122			__u32 ptr;
123#else
124			__u32 ptr;
125			__u32 padding;		/* Initialized to zero. */
126#endif
127		} arch;
128	} rseq_cs;
129
130	/*
131	 * Restartable sequences flags field.
132	 *
133	 * This field should only be updated by the thread which
134	 * registered this data structure. Read by the kernel.
135	 * Mainly used for single-stepping through rseq critical sections
136	 * with debuggers.
137	 *
138	 * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT
139	 *     Inhibit instruction sequence block restart on preemption
140	 *     for this thread.
141	 * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL
142	 *     Inhibit instruction sequence block restart on signal
143	 *     delivery for this thread.
144	 * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE
145	 *     Inhibit instruction sequence block restart on migration for
146	 *     this thread.
147	 */
148	__u32 flags;
149
150	/*
151	 * Restartable sequences node_id field. Updated by the kernel. Read by
152	 * user-space with single-copy atomicity semantics. This field should
153	 * only be read by the thread which registered this data structure.
154	 * Aligned on 32-bit. Contains the current NUMA node ID.
155	 */
156	__u32 node_id;
157
158	/*
159	 * Restartable sequences mm_cid field. Updated by the kernel. Read by
160	 * user-space with single-copy atomicity semantics. This field should
161	 * only be read by the thread which registered this data structure.
162	 * Aligned on 32-bit. Contains the current thread's concurrency ID
163	 * (allocated uniquely within a memory map).
164	 */
165	__u32 mm_cid;
166
167	/*
168	 * Flexible array member at end of structure, after last feature field.
169	 */
170	char end[];
171} __attribute__((aligned(4 * sizeof(__u64))));
172
173#endif /* _RSEQ_ABI_H */
174