1 | /* Restartable Sequences exported symbols. Linux header. |
2 | Copyright (C) 2021-2022 Free Software Foundation, Inc. |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2.1 of the License, or (at your option) any later version. |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with the GNU C Library; if not, see |
16 | <https://www.gnu.org/licenses/>. */ |
17 | |
18 | #ifndef _SYS_RSEQ_H |
19 | #define _SYS_RSEQ_H 1 |
20 | |
21 | /* Architecture-specific rseq signature. */ |
22 | #include <bits/rseq.h> |
23 | |
24 | #include <stddef.h> |
25 | #include <stdint.h> |
26 | #include <sys/cdefs.h> |
27 | #include <bits/endian.h> |
28 | |
29 | #ifdef __has_include |
30 | # if __has_include ("linux/rseq.h") |
31 | # define __GLIBC_HAVE_KERNEL_RSEQ |
32 | # endif |
33 | #else |
34 | # include <linux/version.h> |
35 | # if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 18, 0) |
36 | # define __GLIBC_HAVE_KERNEL_RSEQ |
37 | # endif |
38 | #endif |
39 | |
40 | #ifdef __GLIBC_HAVE_KERNEL_RSEQ |
41 | /* We use the structures declarations from the kernel headers. */ |
42 | # include <linux/rseq.h> |
43 | #else /* __GLIBC_HAVE_KERNEL_RSEQ */ |
44 | /* We use a copy of the include/uapi/linux/rseq.h kernel header. */ |
45 | |
46 | enum rseq_cpu_id_state |
47 | { |
48 | RSEQ_CPU_ID_UNINITIALIZED = -1, |
49 | RSEQ_CPU_ID_REGISTRATION_FAILED = -2, |
50 | }; |
51 | |
52 | enum rseq_flags |
53 | { |
54 | RSEQ_FLAG_UNREGISTER = (1 << 0), |
55 | }; |
56 | |
57 | enum rseq_cs_flags_bit |
58 | { |
59 | RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0, |
60 | RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1, |
61 | RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2, |
62 | }; |
63 | |
64 | enum rseq_cs_flags |
65 | { |
66 | RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = |
67 | (1U << RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT), |
68 | RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = |
69 | (1U << RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT), |
70 | RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = |
71 | (1U << RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT), |
72 | }; |
73 | |
74 | /* struct rseq_cs is aligned on 32 bytes to ensure it is always |
75 | contained within a single cache-line. It is usually declared as |
76 | link-time constant data. */ |
77 | struct rseq_cs |
78 | { |
79 | /* Version of this structure. */ |
80 | uint32_t version; |
81 | /* enum rseq_cs_flags. */ |
82 | uint32_t flags; |
83 | uint64_t start_ip; |
84 | /* Offset from start_ip. */ |
85 | uint64_t post_commit_offset; |
86 | uint64_t abort_ip; |
87 | } __attribute__ ((__aligned__ (32))); |
88 | |
89 | /* struct rseq is aligned on 32 bytes to ensure it is always |
90 | contained within a single cache-line. |
91 | |
92 | A single struct rseq per thread is allowed. */ |
93 | struct rseq |
94 | { |
95 | /* Restartable sequences cpu_id_start field. Updated by the |
96 | kernel. Read by user-space with single-copy atomicity |
97 | semantics. This field should only be read by the thread which |
98 | registered this data structure. Aligned on 32-bit. Always |
99 | contains a value in the range of possible CPUs, although the |
100 | value may not be the actual current CPU (e.g. if rseq is not |
101 | initialized). This CPU number value should always be compared |
102 | against the value of the cpu_id field before performing a rseq |
103 | commit or returning a value read from a data structure indexed |
104 | using the cpu_id_start value. */ |
105 | uint32_t cpu_id_start; |
106 | /* Restartable sequences cpu_id field. Updated by the kernel. |
107 | Read by user-space with single-copy atomicity semantics. This |
108 | field should only be read by the thread which registered this |
109 | data structure. Aligned on 32-bit. Values |
110 | RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED |
111 | have a special semantic: the former means "rseq uninitialized", |
112 | and latter means "rseq initialization failed". This value is |
113 | meant to be read within rseq critical sections and compared |
114 | with the cpu_id_start value previously read, before performing |
115 | the commit instruction, or read and compared with the |
116 | cpu_id_start value before returning a value loaded from a data |
117 | structure indexed using the cpu_id_start value. */ |
118 | uint32_t cpu_id; |
119 | /* Restartable sequences rseq_cs field. |
120 | |
121 | Contains NULL when no critical section is active for the current |
122 | thread, or holds a pointer to the currently active struct rseq_cs. |
123 | |
124 | Updated by user-space, which sets the address of the currently |
125 | active rseq_cs at the beginning of assembly instruction sequence |
126 | block, and set to NULL by the kernel when it restarts an assembly |
127 | instruction sequence block, as well as when the kernel detects that |
128 | it is preempting or delivering a signal outside of the range |
129 | targeted by the rseq_cs. Also needs to be set to NULL by user-space |
130 | before reclaiming memory that contains the targeted struct rseq_cs. |
131 | |
132 | Read and set by the kernel. Set by user-space with single-copy |
133 | atomicity semantics. This field should only be updated by the |
134 | thread which registered this data structure. Aligned on 64-bit. */ |
135 | union |
136 | { |
137 | uint64_t ptr64; |
138 | # ifdef __LP64__ |
139 | uint64_t ptr; |
140 | # else /* __LP64__ */ |
141 | struct |
142 | { |
143 | #if __BYTE_ORDER == __BIG_ENDIAN |
144 | uint32_t padding; /* Initialized to zero. */ |
145 | uint32_t ptr32; |
146 | # else /* LITTLE */ |
147 | uint32_t ptr32; |
148 | uint32_t padding; /* Initialized to zero. */ |
149 | # endif /* ENDIAN */ |
150 | } ptr; |
151 | # endif /* __LP64__ */ |
152 | } rseq_cs; |
153 | |
154 | /* Restartable sequences flags field. |
155 | |
156 | This field should only be updated by the thread which |
157 | registered this data structure. Read by the kernel. |
158 | Mainly used for single-stepping through rseq critical sections |
159 | with debuggers. |
160 | |
161 | - RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT |
162 | Inhibit instruction sequence block restart on preemption |
163 | for this thread. |
164 | - RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL |
165 | Inhibit instruction sequence block restart on signal |
166 | delivery for this thread. |
167 | - RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE |
168 | Inhibit instruction sequence block restart on migration for |
169 | this thread. */ |
170 | uint32_t flags; |
171 | } __attribute__ ((__aligned__ (32))); |
172 | |
173 | #endif /* __GLIBC_HAVE_KERNEL_RSEQ */ |
174 | |
175 | /* Offset from the thread pointer to the rseq area. */ |
176 | extern const ptrdiff_t __rseq_offset; |
177 | |
178 | /* Size of the registered rseq area. 0 if the registration was |
179 | unsuccessful. */ |
180 | extern const unsigned int __rseq_size; |
181 | |
182 | /* Flags used during rseq registration. */ |
183 | extern const unsigned int __rseq_flags; |
184 | |
185 | #endif /* sys/rseq.h */ |
186 | |