1 | /* Restartable Sequences exported symbols. Linux header. |
2 | Copyright (C) 2021-2024 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 | |
28 | #ifdef __has_include |
29 | # if __has_include ("linux/rseq.h") |
30 | # define __GLIBC_HAVE_KERNEL_RSEQ |
31 | # endif |
32 | #else |
33 | # include <linux/version.h> |
34 | # if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 18, 0) |
35 | # define __GLIBC_HAVE_KERNEL_RSEQ |
36 | # endif |
37 | #endif |
38 | |
39 | #ifdef __GLIBC_HAVE_KERNEL_RSEQ |
40 | /* We use the structures declarations from the kernel headers. */ |
41 | # include <linux/rseq.h> |
42 | #else /* __GLIBC_HAVE_KERNEL_RSEQ */ |
43 | /* We use a copy of the include/uapi/linux/rseq.h kernel header. */ |
44 | |
45 | enum rseq_cpu_id_state |
46 | { |
47 | RSEQ_CPU_ID_UNINITIALIZED = -1, |
48 | RSEQ_CPU_ID_REGISTRATION_FAILED = -2, |
49 | }; |
50 | |
51 | enum rseq_flags |
52 | { |
53 | RSEQ_FLAG_UNREGISTER = (1 << 0), |
54 | }; |
55 | |
56 | enum rseq_cs_flags_bit |
57 | { |
58 | RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0, |
59 | RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1, |
60 | RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2, |
61 | }; |
62 | |
63 | enum rseq_cs_flags |
64 | { |
65 | RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = |
66 | (1U << RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT), |
67 | RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = |
68 | (1U << RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT), |
69 | RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = |
70 | (1U << RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT), |
71 | }; |
72 | |
73 | /* struct rseq_cs is aligned on 32 bytes to ensure it is always |
74 | contained within a single cache-line. It is usually declared as |
75 | link-time constant data. */ |
76 | struct rseq_cs |
77 | { |
78 | /* Version of this structure. */ |
79 | uint32_t version; |
80 | /* enum rseq_cs_flags. */ |
81 | uint32_t flags; |
82 | uint64_t start_ip; |
83 | /* Offset from start_ip. */ |
84 | uint64_t post_commit_offset; |
85 | uint64_t abort_ip; |
86 | } __attribute__ ((__aligned__ (32))); |
87 | |
88 | /* struct rseq is aligned on 32 bytes to ensure it is always |
89 | contained within a single cache-line. |
90 | |
91 | A single struct rseq per thread is allowed. */ |
92 | struct rseq |
93 | { |
94 | /* Restartable sequences cpu_id_start field. Updated by the |
95 | kernel. Read by user-space with single-copy atomicity |
96 | semantics. This field should only be read by the thread which |
97 | registered this data structure. Aligned on 32-bit. Always |
98 | contains a value in the range of possible CPUs, although the |
99 | value may not be the actual current CPU (e.g. if rseq is not |
100 | initialized). This CPU number value should always be compared |
101 | against the value of the cpu_id field before performing a rseq |
102 | commit or returning a value read from a data structure indexed |
103 | using the cpu_id_start value. */ |
104 | uint32_t cpu_id_start; |
105 | /* Restartable sequences cpu_id field. Updated by the kernel. |
106 | Read by user-space with single-copy atomicity semantics. This |
107 | field should only be read by the thread which registered this |
108 | data structure. Aligned on 32-bit. Values |
109 | RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED |
110 | have a special semantic: the former means "rseq uninitialized", |
111 | and latter means "rseq initialization failed". This value is |
112 | meant to be read within rseq critical sections and compared |
113 | with the cpu_id_start value previously read, before performing |
114 | the commit instruction, or read and compared with the |
115 | cpu_id_start value before returning a value loaded from a data |
116 | structure indexed using the cpu_id_start value. */ |
117 | uint32_t cpu_id; |
118 | /* Restartable sequences rseq_cs field. |
119 | |
120 | Contains NULL when no critical section is active for the current |
121 | thread, or holds a pointer to the currently active struct rseq_cs. |
122 | |
123 | Updated by user-space, which sets the address of the currently |
124 | active rseq_cs at the beginning of assembly instruction sequence |
125 | block, and set to NULL by the kernel when it restarts an assembly |
126 | instruction sequence block, as well as when the kernel detects that |
127 | it is preempting or delivering a signal outside of the range |
128 | targeted by the rseq_cs. Also needs to be set to NULL by user-space |
129 | before reclaiming memory that contains the targeted struct rseq_cs. |
130 | |
131 | Read and set by the kernel. Set by user-space with single-copy |
132 | atomicity semantics. This field should only be updated by the |
133 | thread which registered this data structure. Aligned on 64-bit. |
134 | |
135 | 32-bit architectures should update the low order bits of the |
136 | rseq_cs field, leaving the high order bits initialized to 0. */ |
137 | uint64_t rseq_cs; |
138 | /* Restartable sequences flags field. |
139 | |
140 | This field should only be updated by the thread which |
141 | registered this data structure. Read by the kernel. |
142 | Mainly used for single-stepping through rseq critical sections |
143 | with debuggers. |
144 | |
145 | - RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT |
146 | Inhibit instruction sequence block restart on preemption |
147 | for this thread. |
148 | - RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL |
149 | Inhibit instruction sequence block restart on signal |
150 | delivery for this thread. |
151 | - RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE |
152 | Inhibit instruction sequence block restart on migration for |
153 | this thread. */ |
154 | uint32_t flags; |
155 | } __attribute__ ((__aligned__ (32))); |
156 | |
157 | #endif /* __GLIBC_HAVE_KERNEL_RSEQ */ |
158 | |
159 | /* Offset from the thread pointer to the rseq area. */ |
160 | extern const ptrdiff_t __rseq_offset; |
161 | |
162 | /* Size of the registered rseq area. 0 if the registration was |
163 | unsuccessful. */ |
164 | extern const unsigned int __rseq_size; |
165 | |
166 | /* Flags used during rseq registration. */ |
167 | extern const unsigned int __rseq_flags; |
168 | |
169 | #endif /* sys/rseq.h */ |
170 | |