Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/xtensa/kernel/signal.c
26424 views
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 <[email protected]>
15
* Joe Taylor <[email protected]>
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
&regs->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
&regs->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), &regs->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 (sc->sc_a, regs->areg, 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, &regs->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(regs->areg, sc->sc_a, 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(&regs->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("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(&set, &frame->uc.uc_sigmask, 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 ("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(&frame->info, &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(&frame->uc.uc_sigmask, set, 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(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, handler, (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)) {
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, sigmask_to_save(), regs);
495
signal_setup_done(ret, &ksig, 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
537