Branch data Line data Source code
1 : : #ifndef __CR_RESTORER_H__
2 : : #define __CR_RESTORER_H__
3 : :
4 : : #include <signal.h>
5 : : #include <limits.h>
6 : :
7 : : #include "compiler.h"
8 : : #include "types.h"
9 : : #include "image.h"
10 : : #include "lock.h"
11 : : #include "util.h"
12 : : #include "crtools.h"
13 : : #include "fpu.h"
14 : :
15 : : #include "../protobuf/mm.pb-c.h"
16 : : #include "../protobuf/vma.pb-c.h"
17 : : #include "../protobuf/creds.pb-c.h"
18 : : #include "../protobuf/core.pb-c.h"
19 : :
20 : : #ifndef CONFIG_X86_64
21 : : # error Only x86-64 is supported
22 : : #endif
23 : :
24 : : struct task_restore_core_args;
25 : : struct thread_restore_args;
26 : :
27 : : typedef long (*task_restore_fcall_t) (struct task_restore_core_args *args);
28 : : typedef long (*thread_restore_fcall_t) (struct thread_restore_args *args);
29 : :
30 : : #define RESTORE_CMD__NONE 0
31 : : #define RESTORE_CMD__GET_SELF_LEN 1
32 : : #define RESTORE_CMD__RESTORE_CORE 2
33 : : #define RESTORE_CMD__RESTORE_THREAD 3
34 : :
35 : : /*
36 : : * These *must* be power of two values.
37 : : */
38 : : #define RESTORE_ARGS_SIZE (512)
39 : : #define RESTORE_STACK_REDZONE (128)
40 : : #define RESTORE_STACK_SIGFRAME (KILO(16))
41 : : #define RESTORE_STACK_SIZE (KILO(32))
42 : : #define RESTORE_HEAP_SIZE (KILO(16))
43 : :
44 : : #define RESTORE_ALIGN_STACK(start, size) \
45 : : (ALIGN((start) + (size) - sizeof(long), sizeof(long)))
46 : :
47 : : struct restore_mem_zone {
48 : : u8 redzone[RESTORE_STACK_REDZONE];
49 : : u8 stack[RESTORE_STACK_SIZE];
50 : : u8 rt_sigframe[RESTORE_STACK_SIGFRAME];
51 : : u8 heap[RESTORE_HEAP_SIZE];
52 : : } __aligned(sizeof(long));
53 : :
54 : : #define first_on_heap(ptr, heap) ((typeof(ptr))heap)
55 : : #define next_on_heap(ptr, prev) ((typeof(ptr))((long)(prev) + sizeof(*(prev))))
56 : :
57 : : struct rst_sched_param {
58 : : int policy;
59 : : int nice;
60 : : int prio;
61 : : };
62 : :
63 : : struct task_restore_core_args;
64 : :
65 : : /* Make sure it's pow2 in size */
66 : : struct thread_restore_args {
67 : : struct restore_mem_zone mem_zone;
68 : :
69 : : int pid;
70 : : UserX86RegsEntry gpregs;
71 : : u64 clear_tid_addr;
72 : :
73 : : bool has_futex;
74 : : u64 futex_rla;
75 : : u32 futex_rla_len;
76 : :
77 : : bool has_blk_sigset;
78 : : u64 blk_sigset;
79 : :
80 : : struct rst_sched_param sp;
81 : :
82 : : struct task_restore_core_args *ta;
83 : :
84 : : /*
85 : : * The FPU xsave area must be continious and FP_MIN_ALIGN_BYTES
86 : : * aligned, thus make sure the compiler won't insert any hole here.
87 : : */
88 : : bool has_fpu;
89 : : union {
90 : : struct xsave_struct xsave;
91 : : unsigned char __pad[sizeof(struct xsave_struct) + FP_XSTATE_MAGIC2_SIZE];
92 : : };
93 : : } __aligned(sizeof(long));
94 : :
95 : : struct task_restore_core_args {
96 : : struct thread_restore_args *t; /* thread group leader */
97 : :
98 : : int fd_exe_link; /* opened self->exe file */
99 : : int logfd;
100 : : unsigned int loglevel;
101 : :
102 : : mutex_t rst_lock;
103 : :
104 : : /* threads restoration */
105 : : int nr_threads; /* number of threads */
106 : : thread_restore_fcall_t clone_restore_fn; /* helper address for clone() call */
107 : : struct thread_restore_args *thread_args; /* array of thread arguments */
108 : : struct shmems *shmems;
109 : : struct task_entries *task_entries;
110 : : VmaEntry *self_vmas;
111 : : VmaEntry *tgt_vmas;
112 : : unsigned int nr_vmas;
113 : : unsigned long premmapped_addr;
114 : : unsigned long premmapped_len;
115 : : rt_sigaction_t sigchld_act;
116 : :
117 : : struct itimerval itimers[3];
118 : :
119 : : CredsEntry creds;
120 : : uint32_t cap_inh[CR_CAP_SIZE];
121 : : uint32_t cap_prm[CR_CAP_SIZE];
122 : : uint32_t cap_eff[CR_CAP_SIZE];
123 : : uint32_t cap_bnd[CR_CAP_SIZE];
124 : :
125 : : MmEntry mm;
126 : : u64 mm_saved_auxv[AT_VECTOR_SIZE];
127 : : u32 mm_saved_auxv_size;
128 : : char comm[TASK_COMM_LEN];
129 : :
130 : : int *rst_tcp_socks;
131 : : int rst_tcp_socks_size;
132 : : } __aligned(sizeof(long));
133 : :
134 : : struct pt_regs {
135 : : unsigned long r15;
136 : : unsigned long r14;
137 : : unsigned long r13;
138 : : unsigned long r12;
139 : : unsigned long bp;
140 : : unsigned long bx;
141 : :
142 : : unsigned long r11;
143 : : unsigned long r10;
144 : : unsigned long r9;
145 : : unsigned long r8;
146 : : unsigned long ax;
147 : : unsigned long cx;
148 : : unsigned long dx;
149 : : unsigned long si;
150 : : unsigned long di;
151 : : unsigned long orig_ax;
152 : :
153 : : unsigned long ip;
154 : : unsigned long cs;
155 : : unsigned long flags;
156 : : unsigned long sp;
157 : : unsigned long ss;
158 : : };
159 : :
160 : : struct rt_sigcontext {
161 : : unsigned long r8;
162 : : unsigned long r9;
163 : : unsigned long r10;
164 : : unsigned long r11;
165 : : unsigned long r12;
166 : : unsigned long r13;
167 : : unsigned long r14;
168 : : unsigned long r15;
169 : : unsigned long rdi;
170 : : unsigned long rsi;
171 : : unsigned long rbp;
172 : : unsigned long rbx;
173 : : unsigned long rdx;
174 : : unsigned long rax;
175 : : unsigned long rcx;
176 : : unsigned long rsp;
177 : : unsigned long rip;
178 : : unsigned long eflags;
179 : : unsigned short cs;
180 : : unsigned short gs;
181 : : unsigned short fs;
182 : : unsigned short __pad0;
183 : : unsigned long err;
184 : : unsigned long trapno;
185 : : unsigned long oldmask;
186 : : unsigned long cr2;
187 : : void *fpstate;;
188 : : unsigned long reserved1[8];
189 : : };
190 : :
191 : : #ifndef __ARCH_SI_PREAMBLE_SIZE
192 : : #define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
193 : : #endif
194 : :
195 : : #define SI_MAX_SIZE 128
196 : : #ifndef SI_PAD_SIZE
197 : : #define SI_PAD_SIZE ((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
198 : : #endif
199 : :
200 : : typedef struct rt_siginfo {
201 : : int si_signo;
202 : : int si_errno;
203 : : int si_code;
204 : : int _pad[SI_PAD_SIZE];
205 : : } rt_siginfo_t;
206 : :
207 : : typedef struct rt_sigaltstack {
208 : : void *ss_sp;
209 : : int ss_flags;
210 : : size_t ss_size;
211 : : } rt_stack_t;
212 : :
213 : : struct rt_ucontext {
214 : : unsigned long uc_flags;
215 : : struct rt_ucontext *uc_link;
216 : : rt_stack_t uc_stack;
217 : : struct rt_sigcontext uc_mcontext;
218 : : rt_sigset_t uc_sigmask; /* mask last for extensibility */
219 : : };
220 : :
221 : : struct rt_sigframe {
222 : : char *pretcode;
223 : : struct rt_ucontext uc;
224 : : struct rt_siginfo info;
225 : :
226 : : /* fp state follows here */
227 : : };
228 : :
229 : :
230 : : #define SHMEMS_SIZE 4096
231 : :
232 : : /*
233 : : * pid is a pid of a creater
234 : : * start, end are used for open mapping
235 : : * fd is a file discriptor, which is valid for creater,
236 : : * it's opened in cr-restor, because pgoff may be non zero
237 : : */
238 : :
239 : : struct shmem_info {
240 : : unsigned long shmid;
241 : : unsigned long start;
242 : : unsigned long end;
243 : : unsigned long size;
244 : : int pid;
245 : : int fd;
246 : : futex_t lock;
247 : : };
248 : :
249 : : struct shmems {
250 : : int nr_shmems;
251 : : struct shmem_info entries[0];
252 : : };
253 : :
254 : : #define TASK_ENTRIES_SIZE 4096
255 : :
256 : : enum {
257 : : CR_STATE_FORKING,
258 : : CR_STATE_RESTORE_PGID,
259 : : CR_STATE_RESTORE,
260 : : CR_STATE_RESTORE_SIGCHLD,
261 : : CR_STATE_COMPLETE
262 : : };
263 : :
264 : : struct task_entries {
265 : : int nr_threads, nr_tasks, nr_helpers;
266 : : futex_t nr_in_progress;
267 : : futex_t start;
268 : : };
269 : :
270 : : static always_inline struct shmem_info *
271 : : find_shmem(struct shmems *shmems, unsigned long shmid)
272 : : {
273 : : struct shmem_info *si;
274 : : int i;
275 : :
276 [ + - ][ + + ]: 543 : for (i = 0; i < shmems->nr_shmems; i++) {
277 : 481 : si = &shmems->entries[i];
278 [ + + ][ + + ]: 481 : if (si->shmid == shmid)
279 : : return si;
280 : : }
281 : :
282 : : return NULL;
283 : : }
284 : :
285 : : #define restore_finish_stage(__stage) do { \
286 : : futex_dec_and_wake(&task_entries->nr_in_progress); \
287 : : futex_wait_while(&task_entries->start, __stage); \
288 : : } while (0)
289 : :
290 : :
291 : : /* the restorer_blob_offset__ prefix is added by gen_offsets.sh */
292 : : #define restorer_sym(rblob, name) ((void *)(rblob) + restorer_blob_offset__##name)
293 : :
294 : : #define vma_priv(vma) ((vma_entry_is(vma, VMA_AREA_REGULAR)) && \
295 : : (vma_entry_is(vma, VMA_ANON_PRIVATE) || \
296 : : vma_entry_is(vma, VMA_FILE_PRIVATE)))
297 : :
298 : : #endif /* __CR_RESTORER_H__ */
|