Commit | Line | Data |
---|---|---|
2c020ed8 CM |
1 | /* |
2 | * Based on arch/arm/kernel/signal.c | |
3 | * | |
4 | * Copyright (C) 1995-2009 Russell King | |
5 | * Copyright (C) 2012 ARM Ltd. | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | */ | |
19 | ||
94b07c1f | 20 | #include <linux/cache.h> |
fd92d4a5 | 21 | #include <linux/compat.h> |
2c020ed8 | 22 | #include <linux/errno.h> |
20987de3 | 23 | #include <linux/kernel.h> |
2c020ed8 CM |
24 | #include <linux/signal.h> |
25 | #include <linux/personality.h> | |
26 | #include <linux/freezer.h> | |
47ccb028 | 27 | #include <linux/stddef.h> |
2c020ed8 | 28 | #include <linux/uaccess.h> |
33f08261 | 29 | #include <linux/sizes.h> |
bb4891a6 | 30 | #include <linux/string.h> |
2c020ed8 CM |
31 | #include <linux/tracehook.h> |
32 | #include <linux/ratelimit.h> | |
cf7de27a | 33 | #include <linux/syscalls.h> |
2c020ed8 | 34 | |
8d66772e | 35 | #include <asm/daifflags.h> |
2c020ed8 CM |
36 | #include <asm/debug-monitors.h> |
37 | #include <asm/elf.h> | |
38 | #include <asm/cacheflush.h> | |
39 | #include <asm/ucontext.h> | |
40 | #include <asm/unistd.h> | |
41 | #include <asm/fpsimd.h> | |
17c28958 | 42 | #include <asm/ptrace.h> |
2c020ed8 | 43 | #include <asm/signal32.h> |
f71016a8 | 44 | #include <asm/traps.h> |
2c020ed8 CM |
45 | #include <asm/vdso.h> |
46 | ||
47 | /* | |
48 | * Do a signal return; undo the signal stack. These are aligned to 128-bit. | |
49 | */ | |
50 | struct rt_sigframe { | |
51 | struct siginfo info; | |
52 | struct ucontext uc; | |
20987de3 DM |
53 | }; |
54 | ||
55 | struct frame_record { | |
304ef4e8 WD |
56 | u64 fp; |
57 | u64 lr; | |
2c020ed8 CM |
58 | }; |
59 | ||
20987de3 DM |
60 | struct rt_sigframe_user_layout { |
61 | struct rt_sigframe __user *sigframe; | |
62 | struct frame_record __user *next_frame; | |
bb4891a6 DM |
63 | |
64 | unsigned long size; /* size of allocated sigframe data */ | |
65 | unsigned long limit; /* largest allowed size */ | |
66 | ||
67 | unsigned long fpsimd_offset; | |
68 | unsigned long esr_offset; | |
8cd969d2 | 69 | unsigned long sve_offset; |
33f08261 | 70 | unsigned long extra_offset; |
bb4891a6 | 71 | unsigned long end_offset; |
20987de3 DM |
72 | }; |
73 | ||
33f08261 DM |
74 | #define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16) |
75 | #define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) | |
76 | #define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) | |
77 | ||
bb4891a6 DM |
78 | static void init_user_layout(struct rt_sigframe_user_layout *user) |
79 | { | |
33f08261 DM |
80 | const size_t reserved_size = |
81 | sizeof(user->sigframe->uc.uc_mcontext.__reserved); | |
82 | ||
bb4891a6 DM |
83 | memset(user, 0, sizeof(*user)); |
84 | user->size = offsetof(struct rt_sigframe, uc.uc_mcontext.__reserved); | |
85 | ||
33f08261 DM |
86 | user->limit = user->size + reserved_size; |
87 | ||
88 | user->limit -= TERMINATOR_SIZE; | |
89 | user->limit -= EXTRA_CONTEXT_SIZE; | |
90 | /* Reserve space for extension and terminator ^ */ | |
bb4891a6 DM |
91 | } |
92 | ||
93 | static size_t sigframe_size(struct rt_sigframe_user_layout const *user) | |
94 | { | |
95 | return round_up(max(user->size, sizeof(struct rt_sigframe)), 16); | |
96 | } | |
97 | ||
33f08261 DM |
98 | /* |
99 | * Sanity limit on the approximate maximum size of signal frame we'll | |
100 | * try to generate. Stack alignment padding and the frame record are | |
101 | * not taken into account. This limit is not a guarantee and is | |
102 | * NOT ABI. | |
103 | */ | |
104 | #define SIGFRAME_MAXSZ SZ_64K | |
105 | ||
106 | static int __sigframe_alloc(struct rt_sigframe_user_layout *user, | |
107 | unsigned long *offset, size_t size, bool extend) | |
108 | { | |
109 | size_t padded_size = round_up(size, 16); | |
110 | ||
111 | if (padded_size > user->limit - user->size && | |
112 | !user->extra_offset && | |
113 | extend) { | |
114 | int ret; | |
115 | ||
116 | user->limit += EXTRA_CONTEXT_SIZE; | |
117 | ret = __sigframe_alloc(user, &user->extra_offset, | |
118 | sizeof(struct extra_context), false); | |
119 | if (ret) { | |
120 | user->limit -= EXTRA_CONTEXT_SIZE; | |
121 | return ret; | |
122 | } | |
123 | ||
124 | /* Reserve space for the __reserved[] terminator */ | |
125 | user->size += TERMINATOR_SIZE; | |
126 | ||
127 | /* | |
128 | * Allow expansion up to SIGFRAME_MAXSZ, ensuring space for | |
129 | * the terminator: | |
130 | */ | |
131 | user->limit = SIGFRAME_MAXSZ - TERMINATOR_SIZE; | |
132 | } | |
133 | ||
134 | /* Still not enough space? Bad luck! */ | |
135 | if (padded_size > user->limit - user->size) | |
136 | return -ENOMEM; | |
137 | ||
138 | *offset = user->size; | |
139 | user->size += padded_size; | |
140 | ||
141 | return 0; | |
142 | } | |
143 | ||
bb4322f7 DM |
144 | /* |
145 | * Allocate space for an optional record of <size> bytes in the user | |
146 | * signal frame. The offset from the signal frame base address to the | |
147 | * allocated block is assigned to *offset. | |
148 | */ | |
149 | static int sigframe_alloc(struct rt_sigframe_user_layout *user, | |
150 | unsigned long *offset, size_t size) | |
151 | { | |
33f08261 DM |
152 | return __sigframe_alloc(user, offset, size, true); |
153 | } | |
bb4322f7 | 154 | |
33f08261 DM |
155 | /* Allocate the null terminator record and prevent further allocations */ |
156 | static int sigframe_alloc_end(struct rt_sigframe_user_layout *user) | |
157 | { | |
158 | int ret; | |
bb4322f7 | 159 | |
33f08261 DM |
160 | /* Un-reserve the space reserved for the terminator: */ |
161 | user->limit += TERMINATOR_SIZE; | |
162 | ||
163 | ret = sigframe_alloc(user, &user->end_offset, | |
164 | sizeof(struct _aarch64_ctx)); | |
165 | if (ret) | |
166 | return ret; | |
167 | ||
168 | /* Prevent further allocation: */ | |
169 | user->limit = user->size; | |
bb4322f7 DM |
170 | return 0; |
171 | } | |
172 | ||
bb4891a6 DM |
173 | static void __user *apply_user_offset( |
174 | struct rt_sigframe_user_layout const *user, unsigned long offset) | |
175 | { | |
176 | char __user *base = (char __user *)user->sigframe; | |
177 | ||
178 | return base + offset; | |
179 | } | |
180 | ||
2c020ed8 CM |
181 | static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) |
182 | { | |
65896545 DM |
183 | struct user_fpsimd_state const *fpsimd = |
184 | ¤t->thread.uw.fpsimd_state; | |
2c020ed8 CM |
185 | int err; |
186 | ||
2c020ed8 CM |
187 | /* copy the FP and status/control registers */ |
188 | err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs)); | |
189 | __put_user_error(fpsimd->fpsr, &ctx->fpsr, err); | |
190 | __put_user_error(fpsimd->fpcr, &ctx->fpcr, err); | |
191 | ||
192 | /* copy the magic/size information */ | |
193 | __put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err); | |
194 | __put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err); | |
195 | ||
196 | return err ? -EFAULT : 0; | |
197 | } | |
198 | ||
199 | static int restore_fpsimd_context(struct fpsimd_context __user *ctx) | |
200 | { | |
0abdeff5 | 201 | struct user_fpsimd_state fpsimd; |
2c020ed8 CM |
202 | __u32 magic, size; |
203 | int err = 0; | |
204 | ||
205 | /* check the magic/size information */ | |
206 | __get_user_error(magic, &ctx->head.magic, err); | |
207 | __get_user_error(size, &ctx->head.size, err); | |
208 | if (err) | |
209 | return -EFAULT; | |
210 | if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context)) | |
211 | return -EINVAL; | |
212 | ||
213 | /* copy the FP and status/control registers */ | |
214 | err = __copy_from_user(fpsimd.vregs, ctx->vregs, | |
215 | sizeof(fpsimd.vregs)); | |
216 | __get_user_error(fpsimd.fpsr, &ctx->fpsr, err); | |
217 | __get_user_error(fpsimd.fpcr, &ctx->fpcr, err); | |
218 | ||
8cd969d2 DM |
219 | clear_thread_flag(TIF_SVE); |
220 | ||
2c020ed8 | 221 | /* load the hardware registers from the fpsimd_state structure */ |
c51f9269 AB |
222 | if (!err) |
223 | fpsimd_update_current_state(&fpsimd); | |
2c020ed8 CM |
224 | |
225 | return err ? -EFAULT : 0; | |
226 | } | |
227 | ||
8cd969d2 | 228 | |
47ccb028 DM |
229 | struct user_ctxs { |
230 | struct fpsimd_context __user *fpsimd; | |
8cd969d2 | 231 | struct sve_context __user *sve; |
47ccb028 DM |
232 | }; |
233 | ||
8cd969d2 DM |
234 | #ifdef CONFIG_ARM64_SVE |
235 | ||
236 | static int preserve_sve_context(struct sve_context __user *ctx) | |
237 | { | |
238 | int err = 0; | |
239 | u16 reserved[ARRAY_SIZE(ctx->__reserved)]; | |
240 | unsigned int vl = current->thread.sve_vl; | |
241 | unsigned int vq = 0; | |
242 | ||
243 | if (test_thread_flag(TIF_SVE)) | |
244 | vq = sve_vq_from_vl(vl); | |
245 | ||
246 | memset(reserved, 0, sizeof(reserved)); | |
247 | ||
248 | __put_user_error(SVE_MAGIC, &ctx->head.magic, err); | |
249 | __put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16), | |
250 | &ctx->head.size, err); | |
251 | __put_user_error(vl, &ctx->vl, err); | |
252 | BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved)); | |
253 | err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved)); | |
254 | ||
255 | if (vq) { | |
256 | /* | |
257 | * This assumes that the SVE state has already been saved to | |
258 | * the task struct by calling preserve_fpsimd_context(). | |
259 | */ | |
260 | err |= __copy_to_user((char __user *)ctx + SVE_SIG_REGS_OFFSET, | |
261 | current->thread.sve_state, | |
262 | SVE_SIG_REGS_SIZE(vq)); | |
263 | } | |
264 | ||
265 | return err ? -EFAULT : 0; | |
266 | } | |
267 | ||
268 | static int restore_sve_fpsimd_context(struct user_ctxs *user) | |
269 | { | |
270 | int err; | |
271 | unsigned int vq; | |
0abdeff5 | 272 | struct user_fpsimd_state fpsimd; |
8cd969d2 DM |
273 | struct sve_context sve; |
274 | ||
275 | if (__copy_from_user(&sve, user->sve, sizeof(sve))) | |
276 | return -EFAULT; | |
277 | ||
278 | if (sve.vl != current->thread.sve_vl) | |
279 | return -EINVAL; | |
280 | ||
281 | if (sve.head.size <= sizeof(*user->sve)) { | |
282 | clear_thread_flag(TIF_SVE); | |
283 | goto fpsimd_only; | |
284 | } | |
285 | ||
286 | vq = sve_vq_from_vl(sve.vl); | |
287 | ||
288 | if (sve.head.size < SVE_SIG_CONTEXT_SIZE(vq)) | |
289 | return -EINVAL; | |
290 | ||
291 | /* | |
292 | * Careful: we are about __copy_from_user() directly into | |
293 | * thread.sve_state with preemption enabled, so protection is | |
294 | * needed to prevent a racing context switch from writing stale | |
295 | * registers back over the new data. | |
296 | */ | |
297 | ||
298 | fpsimd_flush_task_state(current); | |
299 | barrier(); | |
300 | /* From now, fpsimd_thread_switch() won't clear TIF_FOREIGN_FPSTATE */ | |
301 | ||
302 | set_thread_flag(TIF_FOREIGN_FPSTATE); | |
303 | barrier(); | |
304 | /* From now, fpsimd_thread_switch() won't touch thread.sve_state */ | |
305 | ||
306 | sve_alloc(current); | |
307 | err = __copy_from_user(current->thread.sve_state, | |
308 | (char __user const *)user->sve + | |
309 | SVE_SIG_REGS_OFFSET, | |
310 | SVE_SIG_REGS_SIZE(vq)); | |
311 | if (err) | |
312 | return -EFAULT; | |
313 | ||
314 | set_thread_flag(TIF_SVE); | |
315 | ||
316 | fpsimd_only: | |
317 | /* copy the FP and status/control registers */ | |
318 | /* restore_sigframe() already checked that user->fpsimd != NULL. */ | |
319 | err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs, | |
320 | sizeof(fpsimd.vregs)); | |
321 | __get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err); | |
322 | __get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err); | |
323 | ||
324 | /* load the hardware registers from the fpsimd_state structure */ | |
325 | if (!err) | |
326 | fpsimd_update_current_state(&fpsimd); | |
327 | ||
328 | return err ? -EFAULT : 0; | |
329 | } | |
330 | ||
331 | #else /* ! CONFIG_ARM64_SVE */ | |
332 | ||
333 | /* Turn any non-optimised out attempts to use these into a link error: */ | |
334 | extern int preserve_sve_context(void __user *ctx); | |
335 | extern int restore_sve_fpsimd_context(struct user_ctxs *user); | |
336 | ||
337 | #endif /* ! CONFIG_ARM64_SVE */ | |
338 | ||
339 | ||
47ccb028 DM |
340 | static int parse_user_sigframe(struct user_ctxs *user, |
341 | struct rt_sigframe __user *sf) | |
342 | { | |
343 | struct sigcontext __user *const sc = &sf->uc.uc_mcontext; | |
bb4891a6 DM |
344 | struct _aarch64_ctx __user *head; |
345 | char __user *base = (char __user *)&sc->__reserved; | |
47ccb028 | 346 | size_t offset = 0; |
bb4891a6 | 347 | size_t limit = sizeof(sc->__reserved); |
33f08261 DM |
348 | bool have_extra_context = false; |
349 | char const __user *const sfp = (char const __user *)sf; | |
47ccb028 DM |
350 | |
351 | user->fpsimd = NULL; | |
8cd969d2 | 352 | user->sve = NULL; |
47ccb028 | 353 | |
bb4891a6 DM |
354 | if (!IS_ALIGNED((unsigned long)base, 16)) |
355 | goto invalid; | |
356 | ||
47ccb028 | 357 | while (1) { |
bb4891a6 | 358 | int err = 0; |
47ccb028 | 359 | u32 magic, size; |
33f08261 DM |
360 | char const __user *userp; |
361 | struct extra_context const __user *extra; | |
362 | u64 extra_datap; | |
363 | u32 extra_size; | |
364 | struct _aarch64_ctx const __user *end; | |
365 | u32 end_magic, end_size; | |
47ccb028 | 366 | |
bb4891a6 | 367 | if (limit - offset < sizeof(*head)) |
47ccb028 DM |
368 | goto invalid; |
369 | ||
bb4891a6 DM |
370 | if (!IS_ALIGNED(offset, 16)) |
371 | goto invalid; | |
372 | ||
373 | head = (struct _aarch64_ctx __user *)(base + offset); | |
47ccb028 DM |
374 | __get_user_error(magic, &head->magic, err); |
375 | __get_user_error(size, &head->size, err); | |
376 | if (err) | |
377 | return err; | |
378 | ||
bb4891a6 DM |
379 | if (limit - offset < size) |
380 | goto invalid; | |
381 | ||
47ccb028 DM |
382 | switch (magic) { |
383 | case 0: | |
384 | if (size) | |
385 | goto invalid; | |
386 | ||
387 | goto done; | |
388 | ||
389 | case FPSIMD_MAGIC: | |
390 | if (user->fpsimd) | |
391 | goto invalid; | |
392 | ||
bb4891a6 | 393 | if (size < sizeof(*user->fpsimd)) |
47ccb028 DM |
394 | goto invalid; |
395 | ||
396 | user->fpsimd = (struct fpsimd_context __user *)head; | |
397 | break; | |
398 | ||
399 | case ESR_MAGIC: | |
400 | /* ignore */ | |
401 | break; | |
402 | ||
8cd969d2 DM |
403 | case SVE_MAGIC: |
404 | if (!system_supports_sve()) | |
405 | goto invalid; | |
406 | ||
407 | if (user->sve) | |
408 | goto invalid; | |
409 | ||
410 | if (size < sizeof(*user->sve)) | |
411 | goto invalid; | |
412 | ||
413 | user->sve = (struct sve_context __user *)head; | |
414 | break; | |
415 | ||
33f08261 DM |
416 | case EXTRA_MAGIC: |
417 | if (have_extra_context) | |
418 | goto invalid; | |
419 | ||
420 | if (size < sizeof(*extra)) | |
421 | goto invalid; | |
422 | ||
423 | userp = (char const __user *)head; | |
424 | ||
425 | extra = (struct extra_context const __user *)userp; | |
426 | userp += size; | |
427 | ||
428 | __get_user_error(extra_datap, &extra->datap, err); | |
429 | __get_user_error(extra_size, &extra->size, err); | |
430 | if (err) | |
431 | return err; | |
432 | ||
433 | /* Check for the dummy terminator in __reserved[]: */ | |
434 | ||
435 | if (limit - offset - size < TERMINATOR_SIZE) | |
436 | goto invalid; | |
437 | ||
438 | end = (struct _aarch64_ctx const __user *)userp; | |
439 | userp += TERMINATOR_SIZE; | |
440 | ||
441 | __get_user_error(end_magic, &end->magic, err); | |
442 | __get_user_error(end_size, &end->size, err); | |
443 | if (err) | |
444 | return err; | |
445 | ||
446 | if (end_magic || end_size) | |
447 | goto invalid; | |
448 | ||
449 | /* Prevent looping/repeated parsing of extra_context */ | |
450 | have_extra_context = true; | |
451 | ||
452 | base = (__force void __user *)extra_datap; | |
453 | if (!IS_ALIGNED((unsigned long)base, 16)) | |
454 | goto invalid; | |
455 | ||
456 | if (!IS_ALIGNED(extra_size, 16)) | |
457 | goto invalid; | |
458 | ||
459 | if (base != userp) | |
460 | goto invalid; | |
461 | ||
462 | /* Reject "unreasonably large" frames: */ | |
463 | if (extra_size > sfp + SIGFRAME_MAXSZ - userp) | |
464 | goto invalid; | |
465 | ||
466 | /* | |
467 | * Ignore trailing terminator in __reserved[] | |
468 | * and start parsing extra data: | |
469 | */ | |
470 | offset = 0; | |
471 | limit = extra_size; | |
abf73988 | 472 | |
96d4f267 | 473 | if (!access_ok(base, limit)) |
abf73988 DM |
474 | goto invalid; |
475 | ||
33f08261 DM |
476 | continue; |
477 | ||
47ccb028 DM |
478 | default: |
479 | goto invalid; | |
480 | } | |
481 | ||
482 | if (size < sizeof(*head)) | |
483 | goto invalid; | |
484 | ||
bb4891a6 | 485 | if (limit - offset < size) |
47ccb028 DM |
486 | goto invalid; |
487 | ||
488 | offset += size; | |
489 | } | |
490 | ||
491 | done: | |
47ccb028 DM |
492 | return 0; |
493 | ||
494 | invalid: | |
495 | return -EINVAL; | |
496 | } | |
497 | ||
2c020ed8 CM |
498 | static int restore_sigframe(struct pt_regs *regs, |
499 | struct rt_sigframe __user *sf) | |
500 | { | |
501 | sigset_t set; | |
502 | int i, err; | |
47ccb028 | 503 | struct user_ctxs user; |
2c020ed8 CM |
504 | |
505 | err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); | |
506 | if (err == 0) | |
507 | set_current_blocked(&set); | |
508 | ||
509 | for (i = 0; i < 31; i++) | |
510 | __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], | |
511 | err); | |
512 | __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); | |
513 | __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); | |
514 | __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); | |
515 | ||
516 | /* | |
517 | * Avoid sys_rt_sigreturn() restarting. | |
518 | */ | |
17c28958 | 519 | forget_syscall(regs); |
2c020ed8 | 520 | |
dbd4d7ca | 521 | err |= !valid_user_regs(®s->user_regs, current); |
47ccb028 DM |
522 | if (err == 0) |
523 | err = parse_user_sigframe(&user, sf); | |
2c020ed8 | 524 | |
8cd969d2 DM |
525 | if (err == 0) { |
526 | if (!user.fpsimd) | |
527 | return -EINVAL; | |
528 | ||
529 | if (user.sve) { | |
530 | if (!system_supports_sve()) | |
531 | return -EINVAL; | |
532 | ||
533 | err = restore_sve_fpsimd_context(&user); | |
534 | } else { | |
535 | err = restore_fpsimd_context(user.fpsimd); | |
536 | } | |
537 | } | |
2c020ed8 CM |
538 | |
539 | return err; | |
540 | } | |
541 | ||
bf4ce5cc | 542 | SYSCALL_DEFINE0(rt_sigreturn) |
2c020ed8 | 543 | { |
3085e164 | 544 | struct pt_regs *regs = current_pt_regs(); |
2c020ed8 CM |
545 | struct rt_sigframe __user *frame; |
546 | ||
547 | /* Always make any pending restarted system calls return -EINTR */ | |
f56141e3 | 548 | current->restart_block.fn = do_no_restart_syscall; |
2c020ed8 CM |
549 | |
550 | /* | |
551 | * Since we stacked the signal on a 128-bit boundary, then 'sp' should | |
552 | * be word aligned here. | |
553 | */ | |
554 | if (regs->sp & 15) | |
555 | goto badframe; | |
556 | ||
557 | frame = (struct rt_sigframe __user *)regs->sp; | |
558 | ||
96d4f267 | 559 | if (!access_ok(frame, sizeof (*frame))) |
2c020ed8 CM |
560 | goto badframe; |
561 | ||
562 | if (restore_sigframe(regs, frame)) | |
563 | goto badframe; | |
564 | ||
207bdae4 | 565 | if (restore_altstack(&frame->uc.uc_stack)) |
2c020ed8 CM |
566 | goto badframe; |
567 | ||
568 | return regs->regs[0]; | |
569 | ||
570 | badframe: | |
f71016a8 | 571 | arm64_notify_segfault(regs->sp); |
2c020ed8 CM |
572 | return 0; |
573 | } | |
574 | ||
94b07c1f DM |
575 | /* |
576 | * Determine the layout of optional records in the signal frame | |
577 | * | |
578 | * add_all: if true, lays out the biggest possible signal frame for | |
579 | * this task; otherwise, generates a layout for the current state | |
580 | * of the task. | |
581 | */ | |
582 | static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, | |
583 | bool add_all) | |
bb4891a6 | 584 | { |
bb4322f7 DM |
585 | int err; |
586 | ||
587 | err = sigframe_alloc(user, &user->fpsimd_offset, | |
588 | sizeof(struct fpsimd_context)); | |
589 | if (err) | |
590 | return err; | |
bb4891a6 DM |
591 | |
592 | /* fault information, if valid */ | |
94b07c1f | 593 | if (add_all || current->thread.fault_code) { |
bb4322f7 DM |
594 | err = sigframe_alloc(user, &user->esr_offset, |
595 | sizeof(struct esr_context)); | |
596 | if (err) | |
597 | return err; | |
bb4891a6 DM |
598 | } |
599 | ||
8cd969d2 DM |
600 | if (system_supports_sve()) { |
601 | unsigned int vq = 0; | |
602 | ||
94b07c1f DM |
603 | if (add_all || test_thread_flag(TIF_SVE)) { |
604 | int vl = sve_max_vl; | |
605 | ||
606 | if (!add_all) | |
607 | vl = current->thread.sve_vl; | |
608 | ||
609 | vq = sve_vq_from_vl(vl); | |
610 | } | |
8cd969d2 DM |
611 | |
612 | err = sigframe_alloc(user, &user->sve_offset, | |
613 | SVE_SIG_CONTEXT_SIZE(vq)); | |
614 | if (err) | |
615 | return err; | |
616 | } | |
617 | ||
33f08261 | 618 | return sigframe_alloc_end(user); |
bb4891a6 DM |
619 | } |
620 | ||
20987de3 | 621 | static int setup_sigframe(struct rt_sigframe_user_layout *user, |
2c020ed8 CM |
622 | struct pt_regs *regs, sigset_t *set) |
623 | { | |
624 | int i, err = 0; | |
20987de3 | 625 | struct rt_sigframe __user *sf = user->sigframe; |
2c020ed8 | 626 | |
304ef4e8 | 627 | /* set up the stack frame for unwinding */ |
20987de3 DM |
628 | __put_user_error(regs->regs[29], &user->next_frame->fp, err); |
629 | __put_user_error(regs->regs[30], &user->next_frame->lr, err); | |
304ef4e8 | 630 | |
2c020ed8 CM |
631 | for (i = 0; i < 31; i++) |
632 | __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], | |
633 | err); | |
634 | __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); | |
635 | __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); | |
636 | __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); | |
637 | ||
638 | __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); | |
639 | ||
640 | err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); | |
641 | ||
0e0276d1 | 642 | if (err == 0) { |
bb4891a6 DM |
643 | struct fpsimd_context __user *fpsimd_ctx = |
644 | apply_user_offset(user, user->fpsimd_offset); | |
0e0276d1 | 645 | err |= preserve_fpsimd_context(fpsimd_ctx); |
0e0276d1 | 646 | } |
2c020ed8 | 647 | |
15af1942 | 648 | /* fault information, if valid */ |
bb4891a6 DM |
649 | if (err == 0 && user->esr_offset) { |
650 | struct esr_context __user *esr_ctx = | |
651 | apply_user_offset(user, user->esr_offset); | |
652 | ||
15af1942 CM |
653 | __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); |
654 | __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); | |
655 | __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); | |
15af1942 CM |
656 | } |
657 | ||
8cd969d2 DM |
658 | /* Scalable Vector Extension state, if present */ |
659 | if (system_supports_sve() && err == 0 && user->sve_offset) { | |
660 | struct sve_context __user *sve_ctx = | |
661 | apply_user_offset(user, user->sve_offset); | |
662 | err |= preserve_sve_context(sve_ctx); | |
663 | } | |
664 | ||
33f08261 DM |
665 | if (err == 0 && user->extra_offset) { |
666 | char __user *sfp = (char __user *)user->sigframe; | |
667 | char __user *userp = | |
668 | apply_user_offset(user, user->extra_offset); | |
669 | ||
670 | struct extra_context __user *extra; | |
671 | struct _aarch64_ctx __user *end; | |
672 | u64 extra_datap; | |
673 | u32 extra_size; | |
674 | ||
675 | extra = (struct extra_context __user *)userp; | |
676 | userp += EXTRA_CONTEXT_SIZE; | |
677 | ||
678 | end = (struct _aarch64_ctx __user *)userp; | |
679 | userp += TERMINATOR_SIZE; | |
680 | ||
681 | /* | |
682 | * extra_datap is just written to the signal frame. | |
683 | * The value gets cast back to a void __user * | |
684 | * during sigreturn. | |
685 | */ | |
686 | extra_datap = (__force u64)userp; | |
687 | extra_size = sfp + round_up(user->size, 16) - userp; | |
688 | ||
689 | __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); | |
690 | __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); | |
691 | __put_user_error(extra_datap, &extra->datap, err); | |
692 | __put_user_error(extra_size, &extra->size, err); | |
693 | ||
694 | /* Add the terminator */ | |
695 | __put_user_error(0, &end->magic, err); | |
696 | __put_user_error(0, &end->size, err); | |
697 | } | |
698 | ||
2c020ed8 | 699 | /* set the "end" magic */ |
bb4891a6 DM |
700 | if (err == 0) { |
701 | struct _aarch64_ctx __user *end = | |
702 | apply_user_offset(user, user->end_offset); | |
703 | ||
704 | __put_user_error(0, &end->magic, err); | |
705 | __put_user_error(0, &end->size, err); | |
706 | } | |
2c020ed8 CM |
707 | |
708 | return err; | |
709 | } | |
710 | ||
20987de3 DM |
711 | static int get_sigframe(struct rt_sigframe_user_layout *user, |
712 | struct ksignal *ksig, struct pt_regs *regs) | |
2c020ed8 CM |
713 | { |
714 | unsigned long sp, sp_top; | |
bb4891a6 DM |
715 | int err; |
716 | ||
717 | init_user_layout(user); | |
94b07c1f | 718 | err = setup_sigframe_layout(user, false); |
bb4891a6 DM |
719 | if (err) |
720 | return err; | |
2c020ed8 | 721 | |
38a7be3c | 722 | sp = sp_top = sigsp(regs->sp, ksig); |
2c020ed8 | 723 | |
20987de3 DM |
724 | sp = round_down(sp - sizeof(struct frame_record), 16); |
725 | user->next_frame = (struct frame_record __user *)sp; | |
726 | ||
bb4891a6 | 727 | sp = round_down(sp, 16) - sigframe_size(user); |
20987de3 | 728 | user->sigframe = (struct rt_sigframe __user *)sp; |
2c020ed8 CM |
729 | |
730 | /* | |
731 | * Check that we can actually write to the signal frame. | |
732 | */ | |
96d4f267 | 733 | if (!access_ok(user->sigframe, sp_top - sp)) |
20987de3 | 734 | return -EFAULT; |
2c020ed8 | 735 | |
20987de3 | 736 | return 0; |
2c020ed8 CM |
737 | } |
738 | ||
304ef4e8 | 739 | static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, |
20987de3 | 740 | struct rt_sigframe_user_layout *user, int usig) |
2c020ed8 | 741 | { |
2c020ed8 | 742 | __sigrestore_t sigtramp; |
2c020ed8 CM |
743 | |
744 | regs->regs[0] = usig; | |
20987de3 DM |
745 | regs->sp = (unsigned long)user->sigframe; |
746 | regs->regs[29] = (unsigned long)&user->next_frame->fp; | |
2c020ed8 CM |
747 | regs->pc = (unsigned long)ka->sa.sa_handler; |
748 | ||
749 | if (ka->sa.sa_flags & SA_RESTORER) | |
750 | sigtramp = ka->sa.sa_restorer; | |
751 | else | |
752 | sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); | |
753 | ||
754 | regs->regs[30] = (unsigned long)sigtramp; | |
2c020ed8 CM |
755 | } |
756 | ||
00554fa4 RW |
757 | static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, |
758 | struct pt_regs *regs) | |
2c020ed8 | 759 | { |
20987de3 | 760 | struct rt_sigframe_user_layout user; |
2c020ed8 | 761 | struct rt_sigframe __user *frame; |
2c020ed8 CM |
762 | int err = 0; |
763 | ||
8cd969d2 DM |
764 | fpsimd_signal_preserve_current_state(); |
765 | ||
20987de3 | 766 | if (get_sigframe(&user, ksig, regs)) |
2c020ed8 CM |
767 | return 1; |
768 | ||
20987de3 DM |
769 | frame = user.sigframe; |
770 | ||
2c020ed8 CM |
771 | __put_user_error(0, &frame->uc.uc_flags, err); |
772 | __put_user_error(NULL, &frame->uc.uc_link, err); | |
773 | ||
207bdae4 | 774 | err |= __save_altstack(&frame->uc.uc_stack, regs->sp); |
20987de3 | 775 | err |= setup_sigframe(&user, regs, set); |
304ef4e8 | 776 | if (err == 0) { |
20987de3 | 777 | setup_return(regs, &ksig->ka, &user, usig); |
00554fa4 RW |
778 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) { |
779 | err |= copy_siginfo_to_user(&frame->info, &ksig->info); | |
304ef4e8 WD |
780 | regs->regs[1] = (unsigned long)&frame->info; |
781 | regs->regs[2] = (unsigned long)&frame->uc; | |
782 | } | |
2c020ed8 CM |
783 | } |
784 | ||
785 | return err; | |
786 | } | |
787 | ||
788 | static void setup_restart_syscall(struct pt_regs *regs) | |
789 | { | |
790 | if (is_compat_task()) | |
791 | compat_setup_restart_syscall(regs); | |
792 | else | |
793 | regs->regs[8] = __NR_restart_syscall; | |
794 | } | |
795 | ||
796 | /* | |
797 | * OK, we're invoking a handler | |
798 | */ | |
00554fa4 | 799 | static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) |
2c020ed8 | 800 | { |
2c020ed8 CM |
801 | struct task_struct *tsk = current; |
802 | sigset_t *oldset = sigmask_to_save(); | |
00554fa4 | 803 | int usig = ksig->sig; |
2c020ed8 CM |
804 | int ret; |
805 | ||
409d5db4 WD |
806 | rseq_signal_deliver(ksig, regs); |
807 | ||
2c020ed8 CM |
808 | /* |
809 | * Set up the stack frame | |
810 | */ | |
811 | if (is_compat_task()) { | |
00554fa4 RW |
812 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
813 | ret = compat_setup_rt_frame(usig, ksig, oldset, regs); | |
2c020ed8 | 814 | else |
00554fa4 | 815 | ret = compat_setup_frame(usig, ksig, oldset, regs); |
2c020ed8 | 816 | } else { |
00554fa4 | 817 | ret = setup_rt_frame(usig, ksig, oldset, regs); |
2c020ed8 CM |
818 | } |
819 | ||
820 | /* | |
821 | * Check that the resulting registers are actually sane. | |
822 | */ | |
dbd4d7ca | 823 | ret |= !valid_user_regs(®s->user_regs, current); |
2c020ed8 | 824 | |
2c020ed8 CM |
825 | /* |
826 | * Fast forward the stepping logic so we step into the signal | |
827 | * handler. | |
828 | */ | |
00554fa4 RW |
829 | if (!ret) |
830 | user_fastforward_single_step(tsk); | |
2c020ed8 | 831 | |
00554fa4 | 832 | signal_setup_done(ret, ksig, 0); |
2c020ed8 CM |
833 | } |
834 | ||
835 | /* | |
836 | * Note that 'init' is a special process: it doesn't get signals it doesn't | |
837 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | |
838 | * mistake. | |
839 | * | |
840 | * Note that we go through the signals twice: once to check the signals that | |
841 | * the kernel can handle, and then we build all the user-level signal handling | |
842 | * stack-frames in one go after that. | |
843 | */ | |
844 | static void do_signal(struct pt_regs *regs) | |
845 | { | |
846 | unsigned long continue_addr = 0, restart_addr = 0; | |
00554fa4 | 847 | int retval = 0; |
00554fa4 | 848 | struct ksignal ksig; |
0fe42512 | 849 | bool syscall = in_syscall(regs); |
2c020ed8 CM |
850 | |
851 | /* | |
852 | * If we were from a system call, check for system call restarting... | |
853 | */ | |
0fe42512 | 854 | if (syscall) { |
2c020ed8 CM |
855 | continue_addr = regs->pc; |
856 | restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4); | |
857 | retval = regs->regs[0]; | |
858 | ||
859 | /* | |
860 | * Avoid additional syscall restarting via ret_to_user. | |
861 | */ | |
17c28958 | 862 | forget_syscall(regs); |
2c020ed8 CM |
863 | |
864 | /* | |
865 | * Prepare for system call restart. We do this here so that a | |
866 | * debugger will see the already changed PC. | |
867 | */ | |
868 | switch (retval) { | |
869 | case -ERESTARTNOHAND: | |
870 | case -ERESTARTSYS: | |
871 | case -ERESTARTNOINTR: | |
872 | case -ERESTART_RESTARTBLOCK: | |
873 | regs->regs[0] = regs->orig_x0; | |
874 | regs->pc = restart_addr; | |
875 | break; | |
876 | } | |
877 | } | |
878 | ||
879 | /* | |
880 | * Get the signal to deliver. When running under ptrace, at this point | |
881 | * the debugger may change all of our registers. | |
882 | */ | |
00554fa4 | 883 | if (get_signal(&ksig)) { |
2c020ed8 CM |
884 | /* |
885 | * Depending on the signal settings, we may need to revert the | |
886 | * decision to restart the system call, but skip this if a | |
887 | * debugger has chosen to restart at a different PC. | |
888 | */ | |
889 | if (regs->pc == restart_addr && | |
890 | (retval == -ERESTARTNOHAND || | |
891 | retval == -ERESTART_RESTARTBLOCK || | |
892 | (retval == -ERESTARTSYS && | |
00554fa4 | 893 | !(ksig.ka.sa.sa_flags & SA_RESTART)))) { |
2c020ed8 CM |
894 | regs->regs[0] = -EINTR; |
895 | regs->pc = continue_addr; | |
896 | } | |
897 | ||
00554fa4 | 898 | handle_signal(&ksig, regs); |
2c020ed8 CM |
899 | return; |
900 | } | |
901 | ||
902 | /* | |
903 | * Handle restarting a different system call. As above, if a debugger | |
904 | * has chosen to restart at a different PC, ignore the restart. | |
905 | */ | |
0fe42512 | 906 | if (syscall && regs->pc == restart_addr) { |
2c020ed8 CM |
907 | if (retval == -ERESTART_RESTARTBLOCK) |
908 | setup_restart_syscall(regs); | |
909 | user_rewind_single_step(current); | |
910 | } | |
911 | ||
912 | restore_saved_sigmask(); | |
913 | } | |
914 | ||
915 | asmlinkage void do_notify_resume(struct pt_regs *regs, | |
3eb6f1f9 | 916 | unsigned long thread_flags) |
2c020ed8 | 917 | { |
421dd6fa CM |
918 | /* |
919 | * The assembly code enters us with IRQs off, but it hasn't | |
920 | * informed the tracing code of that for efficiency reasons. | |
921 | * Update the trace code with the current status. | |
922 | */ | |
923 | trace_hardirqs_off(); | |
cf7de27a | 924 | |
421dd6fa | 925 | do { |
a2048e34 TG |
926 | /* Check valid user FS if needed */ |
927 | addr_limit_user_check(); | |
928 | ||
421dd6fa | 929 | if (thread_flags & _TIF_NEED_RESCHED) { |
8d66772e JM |
930 | /* Unmask Debug and SError for the next task */ |
931 | local_daif_restore(DAIF_PROCCTX_NOIRQ); | |
932 | ||
421dd6fa CM |
933 | schedule(); |
934 | } else { | |
8d66772e | 935 | local_daif_restore(DAIF_PROCCTX); |
421dd6fa | 936 | |
9842ceae PA |
937 | if (thread_flags & _TIF_UPROBE) |
938 | uprobe_notify_resume(regs); | |
939 | ||
421dd6fa CM |
940 | if (thread_flags & _TIF_SIGPENDING) |
941 | do_signal(regs); | |
942 | ||
943 | if (thread_flags & _TIF_NOTIFY_RESUME) { | |
944 | clear_thread_flag(TIF_NOTIFY_RESUME); | |
945 | tracehook_notify_resume(regs); | |
409d5db4 | 946 | rseq_handle_notify_resume(NULL, regs); |
421dd6fa CM |
947 | } |
948 | ||
949 | if (thread_flags & _TIF_FOREIGN_FPSTATE) | |
950 | fpsimd_restore_current_state(); | |
951 | } | |
005f78cd | 952 | |
8d66772e | 953 | local_daif_mask(); |
421dd6fa CM |
954 | thread_flags = READ_ONCE(current_thread_info()->flags); |
955 | } while (thread_flags & _TIF_WORK_MASK); | |
2c020ed8 | 956 | } |
94b07c1f DM |
957 | |
958 | unsigned long __ro_after_init signal_minsigstksz; | |
959 | ||
960 | /* | |
961 | * Determine the stack space required for guaranteed signal devliery. | |
962 | * This function is used to populate AT_MINSIGSTKSZ at process startup. | |
963 | * cpufeatures setup is assumed to be complete. | |
964 | */ | |
965 | void __init minsigstksz_setup(void) | |
966 | { | |
967 | struct rt_sigframe_user_layout user; | |
968 | ||
969 | init_user_layout(&user); | |
970 | ||
971 | /* | |
972 | * If this fails, SIGFRAME_MAXSZ needs to be enlarged. It won't | |
973 | * be big enough, but it's our best guess: | |
974 | */ | |
975 | if (WARN_ON(setup_sigframe_layout(&user, true))) | |
976 | return; | |
977 | ||
978 | signal_minsigstksz = sigframe_size(&user) + | |
979 | round_up(sizeof(struct frame_record), 16) + | |
980 | 16; /* max alignment padding */ | |
981 | } |