~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sparc/kernel/signal32.c

Version: ~ [ linux-5.10-rc5 ] ~ [ linux-5.9.10 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.79 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.159 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.208 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.245 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.245 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp