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