sparc64: fix sparse "Should it be static?" warnings in signal32.c
[deliverable/linux.git] / arch / sparc / kernel / signal32.c
CommitLineData
5526b7e4 1/* arch/sparc64/kernel/signal32.c
1da177e4
LT
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
7 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
8 */
9
10#include <linux/sched.h>
11#include <linux/kernel.h>
12#include <linux/signal.h>
13#include <linux/errno.h>
14#include <linux/wait.h>
15#include <linux/ptrace.h>
16#include <linux/unistd.h>
17#include <linux/mm.h>
18#include <linux/tty.h>
1da177e4
LT
19#include <linux/binfmts.h>
20#include <linux/compat.h>
21#include <linux/bitops.h>
95698466 22#include <linux/tracehook.h>
1da177e4
LT
23
24#include <asm/uaccess.h>
25#include <asm/ptrace.h>
1da177e4
LT
26#include <asm/pgtable.h>
27#include <asm/psrcompat.h>
28#include <asm/fpumacro.h>
29#include <asm/visasm.h>
14cc6aba 30#include <asm/compat_signal.h>
d550bbd4 31#include <asm/switch_to.h>
1da177e4 32
5598473a 33#include "sigutil.h"
abaff455 34#include "kernel.h"
5598473a 35
1da177e4
LT
36/* This magic should be in g_upper[0] for all upper parts
37 * to be valid.
38 */
39#define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269
40typedef struct {
41 unsigned int g_upper[8];
42 unsigned int o_upper[8];
43 unsigned int asi;
44} siginfo_extra_v8plus_t;
45
5526b7e4 46struct signal_frame32 {
1da177e4
LT
47 struct sparc_stackf32 ss;
48 __siginfo32_t info;
5598473a 49 /* __siginfo_fpu_t * */ u32 fpu_save;
1da177e4
LT
50 unsigned int insns[2];
51 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
52 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
53 /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
54 siginfo_extra_v8plus_t v8plus;
5598473a
DM
55 /* __siginfo_rwin_t * */u32 rwin_save;
56} __attribute__((aligned(8)));
1da177e4 57
1da177e4
LT
58struct rt_signal_frame32 {
59 struct sparc_stackf32 ss;
60 compat_siginfo_t info;
61 struct pt_regs32 regs;
62 compat_sigset_t mask;
5598473a 63 /* __siginfo_fpu_t * */ u32 fpu_save;
1da177e4 64 unsigned int insns[2];
99b06feb 65 compat_stack_t stack;
1da177e4
LT
66 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
67 /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
68 siginfo_extra_v8plus_t v8plus;
5598473a
DM
69 /* __siginfo_rwin_t * */u32 rwin_save;
70} __attribute__((aligned(8)));
1da177e4 71
ce395960 72int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
1da177e4
LT
73{
74 int err;
75
76 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
77 return -EFAULT;
78
79 /* If you change siginfo_t structure, please be sure
80 this code is fixed accordingly.
81 It should never copy any pad contained in the structure
82 to avoid security leaks, but must copy the generic
83 3 ints plus the relevant union member.
84 This routine must convert siginfo from 64bit to 32bit as well
85 at the same time. */
86 err = __put_user(from->si_signo, &to->si_signo);
87 err |= __put_user(from->si_errno, &to->si_errno);
88 err |= __put_user((short)from->si_code, &to->si_code);
89 if (from->si_code < 0)
90 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
91 else {
92 switch (from->si_code >> 16) {
93 case __SI_TIMER >> 16:
94 err |= __put_user(from->si_tid, &to->si_tid);
95 err |= __put_user(from->si_overrun, &to->si_overrun);
96 err |= __put_user(from->si_int, &to->si_int);
97 break;
98 case __SI_CHLD >> 16:
99 err |= __put_user(from->si_utime, &to->si_utime);
100 err |= __put_user(from->si_stime, &to->si_stime);
101 err |= __put_user(from->si_status, &to->si_status);
102 default:
103 err |= __put_user(from->si_pid, &to->si_pid);
104 err |= __put_user(from->si_uid, &to->si_uid);
105 break;
106 case __SI_FAULT >> 16:
1da177e4
LT
107 err |= __put_user(from->si_trapno, &to->si_trapno);
108 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
109 break;
9c7d3b3a
JS
110 case __SI_POLL >> 16:
111 err |= __put_user(from->si_band, &to->si_band);
112 err |= __put_user(from->si_fd, &to->si_fd);
113 break;
1da177e4
LT
114 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
115 case __SI_MESGQ >> 16:
116 err |= __put_user(from->si_pid, &to->si_pid);
117 err |= __put_user(from->si_uid, &to->si_uid);
118 err |= __put_user(from->si_int, &to->si_int);
119 break;
120 }
121 }
122 return err;
123}
124
125/* CAUTION: This is just a very minimalist implementation for the
126 * sake of compat_sys_rt_sigqueueinfo()
127 */
128int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
129{
130 if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
131 return -EFAULT;
132
133 if (copy_from_user(to, from, 3*sizeof(int)) ||
134 copy_from_user(to->_sifields._pad, from->_sifields._pad,
135 SI_PAD_SIZE))
136 return -EFAULT;
137
138 return 0;
139}
140
5526b7e4 141void do_sigreturn32(struct pt_regs *regs)
1da177e4 142{
5526b7e4 143 struct signal_frame32 __user *sf;
5598473a
DM
144 compat_uptr_t fpu_save;
145 compat_uptr_t rwin_save;
1da177e4 146 unsigned int psr;
5598473a 147 unsigned pc, npc;
1da177e4
LT
148 sigset_t set;
149 unsigned seta[_COMPAT_NSIG_WORDS];
150 int err, i;
151
5526b7e4
DM
152 /* Always make any pending restarted system calls return -EINTR */
153 current_thread_info()->restart_block.fn = do_no_restart_syscall;
154
155 synchronize_user_stack();
156
1da177e4 157 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
5526b7e4 158 sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
1da177e4
LT
159
160 /* 1. Make sure we are not getting garbage from the user */
161 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
162 (((unsigned long) sf) & 3))
163 goto segv;
164
187cd44e
AV
165 if (get_user(pc, &sf->info.si_regs.pc) ||
166 __get_user(npc, &sf->info.si_regs.npc))
167 goto segv;
1da177e4
LT
168
169 if ((pc | npc) & 3)
170 goto segv;
171
172 if (test_thread_flag(TIF_32BIT)) {
173 pc &= 0xffffffff;
174 npc &= 0xffffffff;
175 }
176 regs->tpc = pc;
177 regs->tnpc = npc;
178
179 /* 2. Restore the state */
180 err = __get_user(regs->y, &sf->info.si_regs.y);
181 err |= __get_user(psr, &sf->info.si_regs.psr);
182
183 for (i = UREG_G1; i <= UREG_I7; i++)
184 err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
185 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
186 err |= __get_user(i, &sf->v8plus.g_upper[0]);
187 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
188 unsigned long asi;
189
190 for (i = UREG_G1; i <= UREG_I7; i++)
191 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
192 err |= __get_user(asi, &sf->v8plus.asi);
193 regs->tstate &= ~TSTATE_ASI;
194 regs->tstate |= ((asi & 0xffUL) << 24UL);
195 }
196 }
197
198 /* User can only change condition codes in %tstate. */
199 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
200 regs->tstate |= psr_to_tstate_icc(psr);
201
2678fefe 202 /* Prevent syscall restart. */
28e61036 203 pt_regs_clear_syscall(regs);
2678fefe 204
1da177e4 205 err |= __get_user(fpu_save, &sf->fpu_save);
5598473a
DM
206 if (!err && fpu_save)
207 err |= restore_fpu_state(regs, compat_ptr(fpu_save));
208 err |= __get_user(rwin_save, &sf->rwin_save);
209 if (!err && rwin_save) {
210 if (restore_rwin_state(compat_ptr(rwin_save)))
211 goto segv;
212 }
1da177e4
LT
213 err |= __get_user(seta[0], &sf->info.si_mask);
214 err |= copy_from_user(seta+1, &sf->extramask,
215 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
216 if (err)
217 goto segv;
218 switch (_NSIG_WORDS) {
219 case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
220 case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
221 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
222 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
223 }
faddf598 224 set_current_blocked(&set);
1da177e4
LT
225 return;
226
227segv:
228 force_sig(SIGSEGV, current);
229}
230
1da177e4
LT
231asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
232{
233 struct rt_signal_frame32 __user *sf;
99b06feb 234 unsigned int psr, pc, npc;
5598473a
DM
235 compat_uptr_t fpu_save;
236 compat_uptr_t rwin_save;
1da177e4
LT
237 sigset_t set;
238 compat_sigset_t seta;
1da177e4
LT
239 int err, i;
240
241 /* Always make any pending restarted system calls return -EINTR */
242 current_thread_info()->restart_block.fn = do_no_restart_syscall;
243
244 synchronize_user_stack();
245 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
246 sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
247
248 /* 1. Make sure we are not getting garbage from the user */
249 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
250 (((unsigned long) sf) & 3))
251 goto segv;
252
187cd44e
AV
253 if (get_user(pc, &sf->regs.pc) ||
254 __get_user(npc, &sf->regs.npc))
255 goto segv;
1da177e4
LT
256
257 if ((pc | npc) & 3)
258 goto segv;
259
260 if (test_thread_flag(TIF_32BIT)) {
261 pc &= 0xffffffff;
262 npc &= 0xffffffff;
263 }
264 regs->tpc = pc;
265 regs->tnpc = npc;
266
267 /* 2. Restore the state */
268 err = __get_user(regs->y, &sf->regs.y);
269 err |= __get_user(psr, &sf->regs.psr);
270
271 for (i = UREG_G1; i <= UREG_I7; i++)
272 err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]);
273 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
274 err |= __get_user(i, &sf->v8plus.g_upper[0]);
275 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
276 unsigned long asi;
277
278 for (i = UREG_G1; i <= UREG_I7; i++)
279 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
280 err |= __get_user(asi, &sf->v8plus.asi);
281 regs->tstate &= ~TSTATE_ASI;
282 regs->tstate |= ((asi & 0xffUL) << 24UL);
283 }
284 }
285
286 /* User can only change condition codes in %tstate. */
287 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
288 regs->tstate |= psr_to_tstate_icc(psr);
289
2678fefe 290 /* Prevent syscall restart. */
28e61036 291 pt_regs_clear_syscall(regs);
2678fefe 292
1da177e4 293 err |= __get_user(fpu_save, &sf->fpu_save);
5598473a
DM
294 if (!err && fpu_save)
295 err |= restore_fpu_state(regs, compat_ptr(fpu_save));
1da177e4 296 err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
99b06feb 297 err |= compat_restore_altstack(&sf->stack);
1da177e4
LT
298 if (err)
299 goto segv;
300
5598473a
DM
301 err |= __get_user(rwin_save, &sf->rwin_save);
302 if (!err && rwin_save) {
303 if (restore_rwin_state(compat_ptr(rwin_save)))
304 goto segv;
305 }
306
1da177e4
LT
307 switch (_NSIG_WORDS) {
308 case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
309 case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
310 case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
311 case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
312 }
faddf598 313 set_current_blocked(&set);
1da177e4
LT
314 return;
315segv:
316 force_sig(SIGSEGV, current);
317}
318
319/* Checks if the fp is valid */
320static int invalid_frame_pointer(void __user *fp, int fplen)
321{
322 if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
323 return 1;
324 return 0;
325}
326
08f73957 327static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
1da177e4
LT
328{
329 unsigned long sp;
330
331 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
332 sp = regs->u_regs[UREG_FP];
333
dc5dc7e6
DM
334 /*
335 * If we are on the alternate signal stack and would overflow it, don't.
336 * Return an always-bogus address instead so we will die with SIGSEGV.
337 */
338 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
339 return (void __user *) -1L;
340
1da177e4 341 /* This is the X/Open sanctioned signal stack switching. */
08f73957 342 sp = sigsp(sp, ksig) - framesize;
f036d9f3 343
dc5dc7e6
DM
344 /* Always align the stack frame. This handles two cases. First,
345 * sigaltstack need not be mindful of platform specific stack
346 * alignment. Second, if we took this signal because the stack
347 * is not aligned properly, we'd like to take the signal cleanly
348 * and report that.
349 */
f036d9f3 350 sp &= ~15UL;
dc5dc7e6 351
f036d9f3 352 return (void __user *) sp;
1da177e4
LT
353}
354
05c5e769
DM
355/* The I-cache flush instruction only works in the primary ASI, which
356 * right now is the nucleus, aka. kernel space.
357 *
358 * Therefore we have to kick the instructions out using the kernel
359 * side linear mapping of the physical address backing the user
360 * instructions.
361 */
362static void flush_signal_insns(unsigned long address)
363{
364 unsigned long pstate, paddr;
365 pte_t *ptep, pte;
366 pgd_t *pgdp;
367 pud_t *pudp;
368 pmd_t *pmdp;
369
370 /* Commit all stores of the instructions we are about to flush. */
371 wmb();
372
373 /* Disable cross-call reception. In this way even a very wide
374 * munmap() on another cpu can't tear down the page table
375 * hierarchy from underneath us, since that can't complete
376 * until the IPI tlb flush returns.
377 */
378
379 __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
380 __asm__ __volatile__("wrpr %0, %1, %%pstate"
381 : : "r" (pstate), "i" (PSTATE_IE));
382
383 pgdp = pgd_offset(current->mm, address);
384 if (pgd_none(*pgdp))
385 goto out_irqs_on;
386 pudp = pud_offset(pgdp, address);
387 if (pud_none(*pudp))
388 goto out_irqs_on;
389 pmdp = pmd_offset(pudp, address);
390 if (pmd_none(*pmdp))
391 goto out_irqs_on;
392
393 ptep = pte_offset_map(pmdp, address);
394 pte = *ptep;
395 if (!pte_present(pte))
396 goto out_unmap;
397
398 paddr = (unsigned long) page_address(pte_page(pte));
399
400 __asm__ __volatile__("flush %0 + %1"
401 : /* no outputs */
402 : "r" (paddr),
403 "r" (address & (PAGE_SIZE - 1))
404 : "memory");
405
406out_unmap:
407 pte_unmap(ptep);
408out_irqs_on:
409 __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
410
411}
412
08f73957
AV
413static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
414 sigset_t *oldset)
1da177e4 415{
5526b7e4 416 struct signal_frame32 __user *sf;
5598473a
DM
417 int i, err, wsaved;
418 void __user *tail;
1da177e4
LT
419 int sigframe_size;
420 u32 psr;
1da177e4
LT
421 unsigned int seta[_COMPAT_NSIG_WORDS];
422
423 /* 1. Make sure everything is clean */
424 synchronize_user_stack();
425 save_and_clear_fpu();
426
5598473a
DM
427 wsaved = get_thread_wsaved();
428
429 sigframe_size = sizeof(*sf);
430 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
431 sigframe_size += sizeof(__siginfo_fpu_t);
432 if (wsaved)
433 sigframe_size += sizeof(__siginfo_rwin_t);
1da177e4 434
5526b7e4 435 sf = (struct signal_frame32 __user *)
08f73957 436 get_sigframe(ksig, regs, sigframe_size);
1da177e4 437
08f73957
AV
438 if (invalid_frame_pointer(sf, sigframe_size)) {
439 do_exit(SIGILL);
440 return -EINVAL;
441 }
1da177e4 442
5598473a 443 tail = (sf + 1);
1da177e4
LT
444
445 /* 2. Save the current process state */
446 if (test_thread_flag(TIF_32BIT)) {
447 regs->tpc &= 0xffffffff;
448 regs->tnpc &= 0xffffffff;
449 }
450 err = put_user(regs->tpc, &sf->info.si_regs.pc);
451 err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
452 err |= __put_user(regs->y, &sf->info.si_regs.y);
453 psr = tstate_to_psr(regs->tstate);
454 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
455 psr |= PSR_EF;
456 err |= __put_user(psr, &sf->info.si_regs.psr);
457 for (i = 0; i < 16; i++)
458 err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
459 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
460 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
461 for (i = 1; i < 16; i++)
462 err |= __put_user(((u32 *)regs->u_regs)[2*i],
463 &sf->v8plus.g_upper[i]);
464 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
465 &sf->v8plus.asi);
466
467 if (psr & PSR_EF) {
5598473a
DM
468 __siginfo_fpu_t __user *fp = tail;
469 tail += sizeof(*fp);
470 err |= save_fpu_state(regs, fp);
471 err |= __put_user((u64)fp, &sf->fpu_save);
1da177e4
LT
472 } else {
473 err |= __put_user(0, &sf->fpu_save);
474 }
5598473a
DM
475 if (wsaved) {
476 __siginfo_rwin_t __user *rwp = tail;
477 tail += sizeof(*rwp);
478 err |= save_rwin_state(wsaved, rwp);
479 err |= __put_user((u64)rwp, &sf->rwin_save);
480 set_thread_wsaved(0);
481 } else {
482 err |= __put_user(0, &sf->rwin_save);
483 }
1da177e4
LT
484
485 switch (_NSIG_WORDS) {
486 case 4: seta[7] = (oldset->sig[3] >> 32);
487 seta[6] = oldset->sig[3];
488 case 3: seta[5] = (oldset->sig[2] >> 32);
489 seta[4] = oldset->sig[2];
490 case 2: seta[3] = (oldset->sig[1] >> 32);
491 seta[2] = oldset->sig[1];
492 case 1: seta[1] = (oldset->sig[0] >> 32);
493 seta[0] = oldset->sig[0];
494 }
495 err |= __put_user(seta[0], &sf->info.si_mask);
496 err |= __copy_to_user(sf->extramask, seta + 1,
497 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
498
5598473a
DM
499 if (!wsaved) {
500 err |= copy_in_user((u32 __user *)sf,
501 (u32 __user *)(regs->u_regs[UREG_FP]),
502 sizeof(struct reg_window32));
503 } else {
504 struct reg_window *rp;
505
506 rp = &current_thread_info()->reg_window[wsaved - 1];
507 for (i = 0; i < 8; i++)
508 err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
509 for (i = 0; i < 6; i++)
510 err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
511 err |= __put_user(rp->ins[6], &sf->ss.fp);
512 err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
513 }
1da177e4 514 if (err)
08f73957 515 return err;
1da177e4
LT
516
517 /* 3. signal handler back-trampoline and parameters */
518 regs->u_regs[UREG_FP] = (unsigned long) sf;
08f73957 519 regs->u_regs[UREG_I0] = ksig->sig;
1da177e4
LT
520 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
521 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
522
523 /* 4. signal handler */
08f73957 524 regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
1da177e4
LT
525 regs->tnpc = (regs->tpc + 4);
526 if (test_thread_flag(TIF_32BIT)) {
527 regs->tpc &= 0xffffffff;
528 regs->tnpc &= 0xffffffff;
529 }
530
531 /* 5. return to kernel instructions */
08f73957
AV
532 if (ksig->ka.ka_restorer) {
533 regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
1da177e4 534 } else {
1da177e4 535 unsigned long address = ((unsigned long)&(sf->insns[0]));
1da177e4
LT
536
537 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
538
539 err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
540 err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
541 if (err)
08f73957 542 return err;
05c5e769 543 flush_signal_insns(address);
1da177e4 544 }
c2785259 545 return 0;
1da177e4
LT
546}
547
08f73957
AV
548static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
549 sigset_t *oldset)
1da177e4
LT
550{
551 struct rt_signal_frame32 __user *sf;
5598473a
DM
552 int i, err, wsaved;
553 void __user *tail;
1da177e4
LT
554 int sigframe_size;
555 u32 psr;
1da177e4
LT
556 compat_sigset_t seta;
557
558 /* 1. Make sure everything is clean */
559 synchronize_user_stack();
560 save_and_clear_fpu();
561
5598473a
DM
562 wsaved = get_thread_wsaved();
563
564 sigframe_size = sizeof(*sf);
565 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
566 sigframe_size += sizeof(__siginfo_fpu_t);
567 if (wsaved)
568 sigframe_size += sizeof(__siginfo_rwin_t);
1da177e4
LT
569
570 sf = (struct rt_signal_frame32 __user *)
08f73957 571 get_sigframe(ksig, regs, sigframe_size);
1da177e4 572
08f73957
AV
573 if (invalid_frame_pointer(sf, sigframe_size)) {
574 do_exit(SIGILL);
575 return -EINVAL;
576 }
1da177e4 577
5598473a 578 tail = (sf + 1);
1da177e4
LT
579
580 /* 2. Save the current process state */
581 if (test_thread_flag(TIF_32BIT)) {
582 regs->tpc &= 0xffffffff;
583 regs->tnpc &= 0xffffffff;
584 }
585 err = put_user(regs->tpc, &sf->regs.pc);
586 err |= __put_user(regs->tnpc, &sf->regs.npc);
587 err |= __put_user(regs->y, &sf->regs.y);
588 psr = tstate_to_psr(regs->tstate);
589 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
590 psr |= PSR_EF;
591 err |= __put_user(psr, &sf->regs.psr);
592 for (i = 0; i < 16; i++)
593 err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
594 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
595 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
596 for (i = 1; i < 16; i++)
597 err |= __put_user(((u32 *)regs->u_regs)[2*i],
598 &sf->v8plus.g_upper[i]);
599 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
600 &sf->v8plus.asi);
601
602 if (psr & PSR_EF) {
5598473a
DM
603 __siginfo_fpu_t __user *fp = tail;
604 tail += sizeof(*fp);
605 err |= save_fpu_state(regs, fp);
606 err |= __put_user((u64)fp, &sf->fpu_save);
1da177e4
LT
607 } else {
608 err |= __put_user(0, &sf->fpu_save);
609 }
5598473a
DM
610 if (wsaved) {
611 __siginfo_rwin_t __user *rwp = tail;
612 tail += sizeof(*rwp);
613 err |= save_rwin_state(wsaved, rwp);
614 err |= __put_user((u64)rwp, &sf->rwin_save);
615 set_thread_wsaved(0);
616 } else {
617 err |= __put_user(0, &sf->rwin_save);
618 }
1da177e4
LT
619
620 /* Update the siginfo structure. */
08f73957 621 err |= copy_siginfo_to_user32(&sf->info, &ksig->info);
1da177e4
LT
622
623 /* Setup sigaltstack */
99b06feb 624 err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
1da177e4
LT
625
626 switch (_NSIG_WORDS) {
627 case 4: seta.sig[7] = (oldset->sig[3] >> 32);
628 seta.sig[6] = oldset->sig[3];
629 case 3: seta.sig[5] = (oldset->sig[2] >> 32);
630 seta.sig[4] = oldset->sig[2];
631 case 2: seta.sig[3] = (oldset->sig[1] >> 32);
632 seta.sig[2] = oldset->sig[1];
633 case 1: seta.sig[1] = (oldset->sig[0] >> 32);
634 seta.sig[0] = oldset->sig[0];
635 }
636 err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
637
5598473a
DM
638 if (!wsaved) {
639 err |= copy_in_user((u32 __user *)sf,
640 (u32 __user *)(regs->u_regs[UREG_FP]),
641 sizeof(struct reg_window32));
642 } else {
643 struct reg_window *rp;
644
645 rp = &current_thread_info()->reg_window[wsaved - 1];
646 for (i = 0; i < 8; i++)
647 err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
648 for (i = 0; i < 6; i++)
649 err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
650 err |= __put_user(rp->ins[6], &sf->ss.fp);
651 err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
652 }
1da177e4 653 if (err)
08f73957 654 return err;
1da177e4
LT
655
656 /* 3. signal handler back-trampoline and parameters */
657 regs->u_regs[UREG_FP] = (unsigned long) sf;
08f73957 658 regs->u_regs[UREG_I0] = ksig->sig;
1da177e4
LT
659 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
660 regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
661
662 /* 4. signal handler */
08f73957 663 regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
1da177e4
LT
664 regs->tnpc = (regs->tpc + 4);
665 if (test_thread_flag(TIF_32BIT)) {
666 regs->tpc &= 0xffffffff;
667 regs->tnpc &= 0xffffffff;
668 }
669
670 /* 5. return to kernel instructions */
08f73957
AV
671 if (ksig->ka.ka_restorer)
672 regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
1da177e4 673 else {
1da177e4 674 unsigned long address = ((unsigned long)&(sf->insns[0]));
1da177e4
LT
675
676 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
677
678 /* mov __NR_rt_sigreturn, %g1 */
679 err |= __put_user(0x82102065, &sf->insns[0]);
680
681 /* t 0x10 */
682 err |= __put_user(0x91d02010, &sf->insns[1]);
683 if (err)
08f73957 684 return err;
1da177e4 685
05c5e769 686 flush_signal_insns(address);
1da177e4 687 }
392c2180 688 return 0;
1da177e4
LT
689}
690
08f73957
AV
691static inline void handle_signal32(struct ksignal *ksig,
692 struct pt_regs *regs)
1da177e4 693{
08f73957 694 sigset_t *oldset = sigmask_to_save();
392c2180
DM
695 int err;
696
08f73957
AV
697 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
698 err = setup_rt_frame32(ksig, regs, oldset);
ec98c6b9 699 else
08f73957 700 err = setup_frame32(ksig, regs, oldset);
392c2180 701
08f73957 702 signal_setup_done(err, ksig, 0);
1da177e4
LT
703}
704
705static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
706 struct sigaction *sa)
707{
708 switch (regs->u_regs[UREG_I0]) {
709 case ERESTART_RESTARTBLOCK:
710 case ERESTARTNOHAND:
711 no_system_call_restart:
712 regs->u_regs[UREG_I0] = EINTR;
713 regs->tstate |= TSTATE_ICARRY;
714 break;
715 case ERESTARTSYS:
716 if (!(sa->sa_flags & SA_RESTART))
717 goto no_system_call_restart;
718 /* fallthrough */
719 case ERESTARTNOINTR:
720 regs->u_regs[UREG_I0] = orig_i0;
721 regs->tpc -= 4;
722 regs->tnpc -= 4;
723 }
724}
725
726/* Note that 'init' is a special process: it doesn't get signals it doesn't
727 * want to handle. Thus you cannot kill init even with a SIGKILL even by
728 * mistake.
729 */
dfbb83d3 730void do_signal32(struct pt_regs * regs)
1da177e4 731{
08f73957
AV
732 struct ksignal ksig;
733 unsigned long orig_i0 = 0;
734 int restart_syscall = 0;
735 bool has_handler = get_signal(&ksig);
28e61036 736
1d299bc7
DM
737 if (pt_regs_is_syscall(regs) &&
738 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
739 restart_syscall = 1;
e88d2468 740 orig_i0 = regs->u_regs[UREG_G6];
1d299bc7 741 }
28e61036 742
08f73957 743 if (has_handler) {
28e61036 744 if (restart_syscall)
08f73957
AV
745 syscall_restart32(orig_i0, regs, &ksig.ka.sa);
746 handle_signal32(&ksig, regs);
747 } else {
748 if (restart_syscall) {
749 switch (regs->u_regs[UREG_I0]) {
750 case ERESTARTNOHAND:
751 case ERESTARTSYS:
752 case ERESTARTNOINTR:
753 /* replay the system call when we are done */
754 regs->u_regs[UREG_I0] = orig_i0;
755 regs->tpc -= 4;
756 regs->tnpc -= 4;
757 pt_regs_clear_syscall(regs);
758 case ERESTART_RESTARTBLOCK:
759 regs->u_regs[UREG_G1] = __NR_restart_syscall;
760 regs->tpc -= 4;
761 regs->tnpc -= 4;
762 pt_regs_clear_syscall(regs);
763 }
764 }
765 restore_saved_sigmask();
1da177e4 766 }
1da177e4
LT
767}
768
769struct sigstack32 {
770 u32 the_stack;
771 int cur_status;
772};
773
774asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
775{
776 struct sigstack32 __user *ssptr =
777 (struct sigstack32 __user *)((unsigned long)(u_ssptr));
778 struct sigstack32 __user *ossptr =
779 (struct sigstack32 __user *)((unsigned long)(u_ossptr));
780 int ret = -EFAULT;
781
782 /* First see if old state is wanted. */
783 if (ossptr) {
784 if (put_user(current->sas_ss_sp + current->sas_ss_size,
785 &ossptr->the_stack) ||
786 __put_user(on_sig_stack(sp), &ossptr->cur_status))
787 goto out;
788 }
789
790 /* Now see if we want to update the new state. */
791 if (ssptr) {
792 u32 ss_sp;
793
794 if (get_user(ss_sp, &ssptr->the_stack))
795 goto out;
796
797 /* If the current stack was set with sigaltstack, don't
798 * swap stacks while we are on it.
799 */
800 ret = -EPERM;
801 if (current->sas_ss_sp && on_sig_stack(sp))
802 goto out;
803
804 /* Since we don't know the extent of the stack, and we don't
805 * track onstack-ness, but rather calculate it, we must
806 * presume a size. Ho hum this interface is lossy.
807 */
808 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
809 current->sas_ss_size = SIGSTKSZ;
810 }
811
812 ret = 0;
813out:
814 return ret;
815}
This page took 1.387937 seconds and 5 git commands to generate.