1 | /* |
2 | * arch/xtensa/kernel/signal.c |
3 | * |
4 | * Default platform functions. |
5 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public |
7 | * License. See the file "COPYING" in the main directory of this archive |
8 | * for more details. |
9 | * |
10 | * Copyright (C) 2005, 2006 Tensilica Inc. |
11 | * Copyright (C) 1991, 1992 Linus Torvalds |
12 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson |
13 | * |
14 | * Chris Zankel <chris@zankel.net> |
15 | * Joe Taylor <joe@tensilica.com> |
16 | */ |
17 | |
18 | #include <linux/signal.h> |
19 | #include <linux/errno.h> |
20 | #include <linux/ptrace.h> |
21 | #include <linux/personality.h> |
22 | #include <linux/resume_user_mode.h> |
23 | #include <linux/sched/task_stack.h> |
24 | |
25 | #include <asm/ucontext.h> |
26 | #include <linux/uaccess.h> |
27 | #include <asm/cacheflush.h> |
28 | #include <asm/coprocessor.h> |
29 | #include <asm/processor.h> |
30 | #include <asm/syscall.h> |
31 | #include <asm/unistd.h> |
32 | |
33 | extern struct task_struct *coproc_owners[]; |
34 | |
35 | struct rt_sigframe |
36 | { |
37 | struct siginfo info; |
38 | struct ucontext uc; |
39 | struct { |
40 | xtregs_opt_t opt; |
41 | xtregs_user_t user; |
42 | #if XTENSA_HAVE_COPROCESSORS |
43 | xtregs_coprocessor_t cp; |
44 | #endif |
45 | } xtregs; |
46 | unsigned char retcode[6]; |
47 | unsigned int window[4]; |
48 | }; |
49 | |
50 | #if defined(USER_SUPPORT_WINDOWED) |
51 | /* |
52 | * Flush register windows stored in pt_regs to stack. |
53 | * Returns 1 for errors. |
54 | */ |
55 | |
56 | static int |
57 | flush_window_regs_user(struct pt_regs *regs) |
58 | { |
59 | const unsigned long ws = regs->windowstart; |
60 | const unsigned long wb = regs->windowbase; |
61 | unsigned long sp = 0; |
62 | unsigned long wm; |
63 | int err = 1; |
64 | int base; |
65 | |
66 | /* Return if no other frames. */ |
67 | |
68 | if (regs->wmask == 1) |
69 | return 0; |
70 | |
71 | /* Rotate windowmask and skip empty frames. */ |
72 | |
73 | wm = (ws >> wb) | (ws << (XCHAL_NUM_AREGS / 4 - wb)); |
74 | base = (XCHAL_NUM_AREGS / 4) - (regs->wmask >> 4); |
75 | |
76 | /* For call8 or call12 frames, we need the previous stack pointer. */ |
77 | |
78 | if ((regs->wmask & 2) == 0) |
79 | if (__get_user(sp, (int*)(regs->areg[base * 4 + 1] - 12))) |
80 | goto errout; |
81 | |
82 | /* Spill frames to stack. */ |
83 | |
84 | while (base < XCHAL_NUM_AREGS / 4) { |
85 | |
86 | int m = (wm >> base); |
87 | int inc = 0; |
88 | |
89 | /* Save registers a4..a7 (call8) or a4...a11 (call12) */ |
90 | |
91 | if (m & 2) { /* call4 */ |
92 | inc = 1; |
93 | |
94 | } else if (m & 4) { /* call8 */ |
95 | if (copy_to_user(&SPILL_SLOT_CALL8(sp, 4), |
96 | ®s->areg[(base + 1) * 4], 16)) |
97 | goto errout; |
98 | inc = 2; |
99 | |
100 | } else if (m & 8) { /* call12 */ |
101 | if (copy_to_user(&SPILL_SLOT_CALL12(sp, 4), |
102 | ®s->areg[(base + 1) * 4], 32)) |
103 | goto errout; |
104 | inc = 3; |
105 | } |
106 | |
107 | /* Save current frame a0..a3 under next SP */ |
108 | |
109 | sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS]; |
110 | if (copy_to_user(&SPILL_SLOT(sp, 0), ®s->areg[base * 4], 16)) |
111 | goto errout; |
112 | |
113 | /* Get current stack pointer for next loop iteration. */ |
114 | |
115 | sp = regs->areg[base * 4 + 1]; |
116 | base += inc; |
117 | } |
118 | |
119 | regs->wmask = 1; |
120 | regs->windowstart = 1 << wb; |
121 | |
122 | return 0; |
123 | |
124 | errout: |
125 | return err; |
126 | } |
127 | #else |
128 | static int |
129 | flush_window_regs_user(struct pt_regs *regs) |
130 | { |
131 | return 0; |
132 | } |
133 | #endif |
134 | |
135 | /* |
136 | * Note: We don't copy double exception 'regs', we have to finish double exc. |
137 | * first before we return to signal handler! This dbl.exc.handler might cause |
138 | * another double exception, but I think we are fine as the situation is the |
139 | * same as if we had returned to the signal handerl and got an interrupt |
140 | * immediately... |
141 | */ |
142 | |
143 | static int |
144 | setup_sigcontext(struct rt_sigframe __user *frame, struct pt_regs *regs) |
145 | { |
146 | struct sigcontext __user *sc = &frame->uc.uc_mcontext; |
147 | struct thread_info *ti = current_thread_info(); |
148 | int err = 0; |
149 | |
150 | #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) |
151 | COPY(pc); |
152 | COPY(ps); |
153 | COPY(lbeg); |
154 | COPY(lend); |
155 | COPY(lcount); |
156 | COPY(sar); |
157 | #undef COPY |
158 | |
159 | err |= flush_window_regs_user(regs); |
160 | err |= __copy_to_user (to: sc->sc_a, from: regs->areg, n: 16 * 4); |
161 | err |= __put_user(0, &sc->sc_xtregs); |
162 | |
163 | if (err) |
164 | return err; |
165 | |
166 | #if XTENSA_HAVE_COPROCESSORS |
167 | coprocessor_flush_release_all(ti); |
168 | err |= __copy_to_user(&frame->xtregs.cp, &ti->xtregs_cp, |
169 | sizeof (frame->xtregs.cp)); |
170 | #endif |
171 | err |= __copy_to_user(&frame->xtregs.opt, ®s->xtregs_opt, |
172 | sizeof (xtregs_opt_t)); |
173 | err |= __copy_to_user(&frame->xtregs.user, &ti->xtregs_user, |
174 | sizeof (xtregs_user_t)); |
175 | |
176 | err |= __put_user(err ? NULL : &frame->xtregs, &sc->sc_xtregs); |
177 | |
178 | return err; |
179 | } |
180 | |
181 | static int |
182 | restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame) |
183 | { |
184 | struct sigcontext __user *sc = &frame->uc.uc_mcontext; |
185 | struct thread_info *ti = current_thread_info(); |
186 | unsigned int err = 0; |
187 | unsigned long ps; |
188 | |
189 | #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) |
190 | COPY(pc); |
191 | COPY(lbeg); |
192 | COPY(lend); |
193 | COPY(lcount); |
194 | COPY(sar); |
195 | #undef COPY |
196 | |
197 | /* All registers were flushed to stack. Start with a pristine frame. */ |
198 | |
199 | regs->wmask = 1; |
200 | regs->windowbase = 0; |
201 | regs->windowstart = 1; |
202 | |
203 | regs->syscall = NO_SYSCALL; /* disable syscall checks */ |
204 | |
205 | /* For PS, restore only PS.CALLINC. |
206 | * Assume that all other bits are either the same as for the signal |
207 | * handler, or the user mode value doesn't matter (e.g. PS.OWB). |
208 | */ |
209 | err |= __get_user(ps, &sc->sc_ps); |
210 | regs->ps = (regs->ps & ~PS_CALLINC_MASK) | (ps & PS_CALLINC_MASK); |
211 | |
212 | /* Additional corruption checks */ |
213 | |
214 | if ((regs->lcount > 0) |
215 | && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) ) |
216 | err = 1; |
217 | |
218 | err |= __copy_from_user(to: regs->areg, from: sc->sc_a, n: 16 * 4); |
219 | |
220 | if (err) |
221 | return err; |
222 | |
223 | /* The signal handler may have used coprocessors in which |
224 | * case they are still enabled. We disable them to force a |
225 | * reloading of the original task's CP state by the lazy |
226 | * context-switching mechanisms of CP exception handling. |
227 | * Also, we essentially discard any coprocessor state that the |
228 | * signal handler created. */ |
229 | |
230 | #if XTENSA_HAVE_COPROCESSORS |
231 | coprocessor_release_all(ti); |
232 | err |= __copy_from_user(&ti->xtregs_cp, &frame->xtregs.cp, |
233 | sizeof (frame->xtregs.cp)); |
234 | #endif |
235 | err |= __copy_from_user(&ti->xtregs_user, &frame->xtregs.user, |
236 | sizeof (xtregs_user_t)); |
237 | err |= __copy_from_user(®s->xtregs_opt, &frame->xtregs.opt, |
238 | sizeof (xtregs_opt_t)); |
239 | |
240 | return err; |
241 | } |
242 | |
243 | |
244 | /* |
245 | * Do a signal return; undo the signal stack. |
246 | */ |
247 | |
248 | asmlinkage long xtensa_rt_sigreturn(void) |
249 | { |
250 | struct pt_regs *regs = current_pt_regs(); |
251 | struct rt_sigframe __user *frame; |
252 | sigset_t set; |
253 | int ret; |
254 | |
255 | /* Always make any pending restarted system calls return -EINTR */ |
256 | current->restart_block.fn = do_no_restart_syscall; |
257 | |
258 | if (regs->depc > 64) |
259 | panic(fmt: "rt_sigreturn in double exception!\n" ); |
260 | |
261 | frame = (struct rt_sigframe __user *) regs->areg[1]; |
262 | |
263 | if (!access_ok(frame, sizeof(*frame))) |
264 | goto badframe; |
265 | |
266 | if (__copy_from_user(to: &set, from: &frame->uc.uc_sigmask, n: sizeof(set))) |
267 | goto badframe; |
268 | |
269 | set_current_blocked(&set); |
270 | |
271 | if (restore_sigcontext(regs, frame)) |
272 | goto badframe; |
273 | |
274 | ret = regs->areg[2]; |
275 | |
276 | if (restore_altstack(&frame->uc.uc_stack)) |
277 | goto badframe; |
278 | |
279 | return ret; |
280 | |
281 | badframe: |
282 | force_sig(SIGSEGV); |
283 | return 0; |
284 | } |
285 | |
286 | |
287 | |
288 | /* |
289 | * Set up a signal frame. |
290 | */ |
291 | |
292 | static int |
293 | gen_return_code(unsigned char *codemem) |
294 | { |
295 | int err = 0; |
296 | |
297 | /* |
298 | * The 12-bit immediate is really split up within the 24-bit MOVI |
299 | * instruction. As long as the above system call numbers fit within |
300 | * 8-bits, the following code works fine. See the Xtensa ISA for |
301 | * details. |
302 | */ |
303 | |
304 | #if __NR_rt_sigreturn > 255 |
305 | # error Generating the MOVI instruction below breaks! |
306 | #endif |
307 | |
308 | #ifdef __XTENSA_EB__ /* Big Endian version */ |
309 | /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ |
310 | err |= __put_user(0x22, &codemem[0]); |
311 | err |= __put_user(0x0a, &codemem[1]); |
312 | err |= __put_user(__NR_rt_sigreturn, &codemem[2]); |
313 | /* Generate instruction: SYSCALL */ |
314 | err |= __put_user(0x00, &codemem[3]); |
315 | err |= __put_user(0x05, &codemem[4]); |
316 | err |= __put_user(0x00, &codemem[5]); |
317 | |
318 | #elif defined __XTENSA_EL__ /* Little Endian version */ |
319 | /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ |
320 | err |= __put_user(0x22, &codemem[0]); |
321 | err |= __put_user(0xa0, &codemem[1]); |
322 | err |= __put_user(__NR_rt_sigreturn, &codemem[2]); |
323 | /* Generate instruction: SYSCALL */ |
324 | err |= __put_user(0x00, &codemem[3]); |
325 | err |= __put_user(0x50, &codemem[4]); |
326 | err |= __put_user(0x00, &codemem[5]); |
327 | #else |
328 | # error Must use compiler for Xtensa processors. |
329 | #endif |
330 | |
331 | /* Flush generated code out of the data cache */ |
332 | |
333 | if (err == 0) { |
334 | __invalidate_icache_range((unsigned long)codemem, 6UL); |
335 | __flush_invalidate_dcache_range((unsigned long)codemem, 6UL); |
336 | } |
337 | |
338 | return err; |
339 | } |
340 | |
341 | |
342 | static int setup_frame(struct ksignal *ksig, sigset_t *set, |
343 | struct pt_regs *regs) |
344 | { |
345 | struct rt_sigframe *frame; |
346 | int err = 0, sig = ksig->sig; |
347 | unsigned long sp, ra, tp, ps; |
348 | unsigned long handler = (unsigned long)ksig->ka.sa.sa_handler; |
349 | unsigned long handler_fdpic_GOT = 0; |
350 | unsigned int base; |
351 | bool fdpic = IS_ENABLED(CONFIG_BINFMT_ELF_FDPIC) && |
352 | (current->personality & FDPIC_FUNCPTRS); |
353 | |
354 | if (fdpic) { |
355 | unsigned long __user *fdpic_func_desc = |
356 | (unsigned long __user *)handler; |
357 | if (__get_user(handler, &fdpic_func_desc[0]) || |
358 | __get_user(handler_fdpic_GOT, &fdpic_func_desc[1])) |
359 | return -EFAULT; |
360 | } |
361 | |
362 | sp = regs->areg[1]; |
363 | |
364 | if ((ksig->ka.sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) { |
365 | sp = current->sas_ss_sp + current->sas_ss_size; |
366 | } |
367 | |
368 | frame = (void *)((sp - sizeof(*frame)) & -16ul); |
369 | |
370 | if (regs->depc > 64) |
371 | panic (fmt: "Double exception sys_sigreturn\n" ); |
372 | |
373 | if (!access_ok(frame, sizeof(*frame))) { |
374 | return -EFAULT; |
375 | } |
376 | |
377 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) { |
378 | err |= copy_siginfo_to_user(to: &frame->info, from: &ksig->info); |
379 | } |
380 | |
381 | /* Create the user context. */ |
382 | |
383 | err |= __put_user(0, &frame->uc.uc_flags); |
384 | err |= __put_user(0, &frame->uc.uc_link); |
385 | err |= __save_altstack(&frame->uc.uc_stack, regs->areg[1]); |
386 | err |= setup_sigcontext(frame, regs); |
387 | err |= __copy_to_user(to: &frame->uc.uc_sigmask, from: set, n: sizeof(*set)); |
388 | |
389 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
390 | if (fdpic) { |
391 | unsigned long __user *fdpic_func_desc = |
392 | (unsigned long __user *)ksig->ka.sa.sa_restorer; |
393 | |
394 | err |= __get_user(ra, fdpic_func_desc); |
395 | } else { |
396 | ra = (unsigned long)ksig->ka.sa.sa_restorer; |
397 | } |
398 | } else { |
399 | |
400 | /* Create sys_rt_sigreturn syscall in stack frame */ |
401 | |
402 | err |= gen_return_code(codemem: frame->retcode); |
403 | ra = (unsigned long) frame->retcode; |
404 | } |
405 | |
406 | if (err) |
407 | return -EFAULT; |
408 | |
409 | /* |
410 | * Create signal handler execution context. |
411 | * Return context not modified until this point. |
412 | */ |
413 | |
414 | /* Set up registers for signal handler; preserve the threadptr */ |
415 | tp = regs->threadptr; |
416 | ps = regs->ps; |
417 | start_thread(regs, new_ip: handler, new_sp: (unsigned long)frame); |
418 | |
419 | /* Set up a stack frame for a call4 if userspace uses windowed ABI */ |
420 | if (ps & PS_WOE_MASK) { |
421 | base = 4; |
422 | regs->areg[base] = |
423 | (((unsigned long) ra) & 0x3fffffff) | 0x40000000; |
424 | ps = (ps & ~(PS_CALLINC_MASK | PS_OWB_MASK)) | |
425 | (1 << PS_CALLINC_SHIFT); |
426 | } else { |
427 | base = 0; |
428 | regs->areg[base] = (unsigned long) ra; |
429 | } |
430 | regs->areg[base + 2] = (unsigned long) sig; |
431 | regs->areg[base + 3] = (unsigned long) &frame->info; |
432 | regs->areg[base + 4] = (unsigned long) &frame->uc; |
433 | regs->threadptr = tp; |
434 | regs->ps = ps; |
435 | if (fdpic) |
436 | regs->areg[base + 11] = handler_fdpic_GOT; |
437 | |
438 | pr_debug("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08lx\n" , |
439 | current->comm, current->pid, sig, frame, regs->pc); |
440 | |
441 | return 0; |
442 | } |
443 | |
444 | /* |
445 | * Note that 'init' is a special process: it doesn't get signals it doesn't |
446 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
447 | * mistake. |
448 | * |
449 | * Note that we go through the signals twice: once to check the signals that |
450 | * the kernel can handle, and then we build all the user-level signal handling |
451 | * stack-frames in one go after that. |
452 | */ |
453 | static void do_signal(struct pt_regs *regs) |
454 | { |
455 | struct ksignal ksig; |
456 | |
457 | task_pt_regs(current)->icountlevel = 0; |
458 | |
459 | if (get_signal(ksig: &ksig)) { |
460 | int ret; |
461 | |
462 | /* Are we from a system call? */ |
463 | |
464 | if (regs->syscall != NO_SYSCALL) { |
465 | |
466 | /* If so, check system call restarting.. */ |
467 | |
468 | switch (regs->areg[2]) { |
469 | case -ERESTARTNOHAND: |
470 | case -ERESTART_RESTARTBLOCK: |
471 | regs->areg[2] = -EINTR; |
472 | break; |
473 | |
474 | case -ERESTARTSYS: |
475 | if (!(ksig.ka.sa.sa_flags & SA_RESTART)) { |
476 | regs->areg[2] = -EINTR; |
477 | break; |
478 | } |
479 | fallthrough; |
480 | case -ERESTARTNOINTR: |
481 | regs->areg[2] = regs->syscall; |
482 | regs->pc -= 3; |
483 | break; |
484 | |
485 | default: |
486 | /* nothing to do */ |
487 | if (regs->areg[2] != 0) |
488 | break; |
489 | } |
490 | } |
491 | |
492 | /* Whee! Actually deliver the signal. */ |
493 | /* Set up the stack frame */ |
494 | ret = setup_frame(ksig: &ksig, set: sigmask_to_save(), regs); |
495 | signal_setup_done(failed: ret, ksig: &ksig, stepping: 0); |
496 | if (test_thread_flag(TIF_SINGLESTEP)) |
497 | task_pt_regs(current)->icountlevel = 1; |
498 | |
499 | return; |
500 | } |
501 | |
502 | /* Did we come from a system call? */ |
503 | if (regs->syscall != NO_SYSCALL) { |
504 | /* Restart the system call - no handlers present */ |
505 | switch (regs->areg[2]) { |
506 | case -ERESTARTNOHAND: |
507 | case -ERESTARTSYS: |
508 | case -ERESTARTNOINTR: |
509 | regs->areg[2] = regs->syscall; |
510 | regs->pc -= 3; |
511 | break; |
512 | case -ERESTART_RESTARTBLOCK: |
513 | regs->areg[2] = __NR_restart_syscall; |
514 | regs->pc -= 3; |
515 | break; |
516 | } |
517 | } |
518 | |
519 | /* If there's no signal to deliver, we just restore the saved mask. */ |
520 | restore_saved_sigmask(); |
521 | |
522 | if (test_thread_flag(TIF_SINGLESTEP)) |
523 | task_pt_regs(current)->icountlevel = 1; |
524 | return; |
525 | } |
526 | |
527 | void do_notify_resume(struct pt_regs *regs) |
528 | { |
529 | if (test_thread_flag(TIF_SIGPENDING) || |
530 | test_thread_flag(TIF_NOTIFY_SIGNAL)) |
531 | do_signal(regs); |
532 | |
533 | if (test_thread_flag(TIF_NOTIFY_RESUME)) |
534 | resume_user_mode_work(regs); |
535 | } |
536 | |