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

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

Version: ~ [ linux-5.5-rc6 ] ~ [ linux-5.4.11 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.95 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.164 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.209 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.209 ] ~ [ 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.81 ] ~ [ 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-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ 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 <asm/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 
 35 /* This magic should be in g_upper[0] for all upper parts
 36  * to be valid.
 37  */
 38 #define SIGINFO_EXTRA_V8PLUS_MAGIC      0x130e269
 39 typedef struct {
 40         unsigned int g_upper[8];
 41         unsigned int o_upper[8];
 42         unsigned int asi;
 43 } siginfo_extra_v8plus_t;
 44 
 45 struct signal_frame32 {
 46         struct sparc_stackf32   ss;
 47         __siginfo32_t           info;
 48         /* __siginfo_fpu_t * */ u32 fpu_save;
 49         unsigned int            insns[2];
 50         unsigned int            extramask[_COMPAT_NSIG_WORDS - 1];
 51         unsigned int            extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
 52         /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
 53         siginfo_extra_v8plus_t  v8plus;
 54         /* __siginfo_rwin_t * */u32 rwin_save;
 55 } __attribute__((aligned(8)));
 56 
 57 typedef struct compat_siginfo{
 58         int si_signo;
 59         int si_errno;
 60         int si_code;
 61 
 62         union {
 63                 int _pad[SI_PAD_SIZE32];
 64 
 65                 /* kill() */
 66                 struct {
 67                         compat_pid_t _pid;              /* sender's pid */
 68                         unsigned int _uid;              /* sender's uid */
 69                 } _kill;
 70 
 71                 /* POSIX.1b timers */
 72                 struct {
 73                         compat_timer_t _tid;                    /* timer id */
 74                         int _overrun;                   /* overrun count */
 75                         compat_sigval_t _sigval;                /* same as below */
 76                         int _sys_private;               /* not to be passed to user */
 77                 } _timer;
 78 
 79                 /* POSIX.1b signals */
 80                 struct {
 81                         compat_pid_t _pid;              /* sender's pid */
 82                         unsigned int _uid;              /* sender's uid */
 83                         compat_sigval_t _sigval;
 84                 } _rt;
 85 
 86                 /* SIGCHLD */
 87                 struct {
 88                         compat_pid_t _pid;              /* which child */
 89                         unsigned int _uid;              /* sender's uid */
 90                         int _status;                    /* exit code */
 91                         compat_clock_t _utime;
 92                         compat_clock_t _stime;
 93                 } _sigchld;
 94 
 95                 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
 96                 struct {
 97                         u32 _addr; /* faulting insn/memory ref. */
 98                         int _trapno;
 99                 } _sigfault;
100 
101                 /* SIGPOLL */
102                 struct {
103                         int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
104                         int _fd;
105                 } _sigpoll;
106         } _sifields;
107 }compat_siginfo_t;
108 
109 struct rt_signal_frame32 {
110         struct sparc_stackf32   ss;
111         compat_siginfo_t        info;
112         struct pt_regs32        regs;
113         compat_sigset_t         mask;
114         /* __siginfo_fpu_t * */ u32 fpu_save;
115         unsigned int            insns[2];
116         stack_t32               stack;
117         unsigned int            extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
118         /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
119         siginfo_extra_v8plus_t  v8plus;
120         /* __siginfo_rwin_t * */u32 rwin_save;
121 } __attribute__((aligned(8)));
122 
123 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
124 {
125         int err;
126 
127         if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
128                 return -EFAULT;
129 
130         /* If you change siginfo_t structure, please be sure
131            this code is fixed accordingly.
132            It should never copy any pad contained in the structure
133            to avoid security leaks, but must copy the generic
134            3 ints plus the relevant union member.
135            This routine must convert siginfo from 64bit to 32bit as well
136            at the same time.  */
137         err = __put_user(from->si_signo, &to->si_signo);
138         err |= __put_user(from->si_errno, &to->si_errno);
139         err |= __put_user((short)from->si_code, &to->si_code);
140         if (from->si_code < 0)
141                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
142         else {
143                 switch (from->si_code >> 16) {
144                 case __SI_TIMER >> 16:
145                         err |= __put_user(from->si_tid, &to->si_tid);
146                         err |= __put_user(from->si_overrun, &to->si_overrun);
147                         err |= __put_user(from->si_int, &to->si_int);
148                         break;
149                 case __SI_CHLD >> 16:
150                         err |= __put_user(from->si_utime, &to->si_utime);
151                         err |= __put_user(from->si_stime, &to->si_stime);
152                         err |= __put_user(from->si_status, &to->si_status);
153                 default:
154                         err |= __put_user(from->si_pid, &to->si_pid);
155                         err |= __put_user(from->si_uid, &to->si_uid);
156                         break;
157                 case __SI_FAULT >> 16:
158                         err |= __put_user(from->si_trapno, &to->si_trapno);
159                         err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
160                         break;
161                 case __SI_POLL >> 16:
162                         err |= __put_user(from->si_band, &to->si_band);
163                         err |= __put_user(from->si_fd, &to->si_fd);
164                         break;
165                 case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
166                 case __SI_MESGQ >> 16:
167                         err |= __put_user(from->si_pid, &to->si_pid);
168                         err |= __put_user(from->si_uid, &to->si_uid);
169                         err |= __put_user(from->si_int, &to->si_int);
170                         break;
171                 }
172         }
173         return err;
174 }
175 
176 /* CAUTION: This is just a very minimalist implementation for the
177  *          sake of compat_sys_rt_sigqueueinfo()
178  */
179 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
180 {
181         if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
182                 return -EFAULT;
183 
184         if (copy_from_user(to, from, 3*sizeof(int)) ||
185             copy_from_user(to->_sifields._pad, from->_sifields._pad,
186                            SI_PAD_SIZE))
187                 return -EFAULT;
188 
189         return 0;
190 }
191 
192 void do_sigreturn32(struct pt_regs *regs)
193 {
194         struct signal_frame32 __user *sf;
195         compat_uptr_t fpu_save;
196         compat_uptr_t rwin_save;
197         unsigned int psr;
198         unsigned pc, npc;
199         sigset_t set;
200         unsigned seta[_COMPAT_NSIG_WORDS];
201         int err, i;
202         
203         /* Always make any pending restarted system calls return -EINTR */
204         current_thread_info()->restart_block.fn = do_no_restart_syscall;
205 
206         synchronize_user_stack();
207 
208         regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
209         sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
210 
211         /* 1. Make sure we are not getting garbage from the user */
212         if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
213             (((unsigned long) sf) & 3))
214                 goto segv;
215 
216         if (get_user(pc, &sf->info.si_regs.pc) ||
217             __get_user(npc, &sf->info.si_regs.npc))
218                 goto segv;
219 
220         if ((pc | npc) & 3)
221                 goto segv;
222 
223         if (test_thread_flag(TIF_32BIT)) {
224                 pc &= 0xffffffff;
225                 npc &= 0xffffffff;
226         }
227         regs->tpc = pc;
228         regs->tnpc = npc;
229 
230         /* 2. Restore the state */
231         err = __get_user(regs->y, &sf->info.si_regs.y);
232         err |= __get_user(psr, &sf->info.si_regs.psr);
233 
234         for (i = UREG_G1; i <= UREG_I7; i++)
235                 err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
236         if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
237                 err |= __get_user(i, &sf->v8plus.g_upper[0]);
238                 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
239                         unsigned long asi;
240 
241                         for (i = UREG_G1; i <= UREG_I7; i++)
242                                 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
243                         err |= __get_user(asi, &sf->v8plus.asi);
244                         regs->tstate &= ~TSTATE_ASI;
245                         regs->tstate |= ((asi & 0xffUL) << 24UL);
246                 }
247         }
248 
249         /* User can only change condition codes in %tstate. */
250         regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
251         regs->tstate |= psr_to_tstate_icc(psr);
252 
253         /* Prevent syscall restart.  */
254         pt_regs_clear_syscall(regs);
255 
256         err |= __get_user(fpu_save, &sf->fpu_save);
257         if (!err && fpu_save)
258                 err |= restore_fpu_state(regs, compat_ptr(fpu_save));
259         err |= __get_user(rwin_save, &sf->rwin_save);
260         if (!err && rwin_save) {
261                 if (restore_rwin_state(compat_ptr(rwin_save)))
262                         goto segv;
263         }
264         err |= __get_user(seta[0], &sf->info.si_mask);
265         err |= copy_from_user(seta+1, &sf->extramask,
266                               (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
267         if (err)
268                 goto segv;
269         switch (_NSIG_WORDS) {
270                 case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
271                 case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
272                 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
273                 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
274         }
275         set_current_blocked(&set);
276         return;
277 
278 segv:
279         force_sig(SIGSEGV, current);
280 }
281 
282 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
283 {
284         struct rt_signal_frame32 __user *sf;
285         unsigned int psr, pc, npc, u_ss_sp;
286         compat_uptr_t fpu_save;
287         compat_uptr_t rwin_save;
288         mm_segment_t old_fs;
289         sigset_t set;
290         compat_sigset_t seta;
291         stack_t st;
292         int err, i;
293         
294         /* Always make any pending restarted system calls return -EINTR */
295         current_thread_info()->restart_block.fn = do_no_restart_syscall;
296 
297         synchronize_user_stack();
298         regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
299         sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
300 
301         /* 1. Make sure we are not getting garbage from the user */
302         if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
303             (((unsigned long) sf) & 3))
304                 goto segv;
305 
306         if (get_user(pc, &sf->regs.pc) || 
307             __get_user(npc, &sf->regs.npc))
308                 goto segv;
309 
310         if ((pc | npc) & 3)
311                 goto segv;
312 
313         if (test_thread_flag(TIF_32BIT)) {
314                 pc &= 0xffffffff;
315                 npc &= 0xffffffff;
316         }
317         regs->tpc = pc;
318         regs->tnpc = npc;
319 
320         /* 2. Restore the state */
321         err = __get_user(regs->y, &sf->regs.y);
322         err |= __get_user(psr, &sf->regs.psr);
323         
324         for (i = UREG_G1; i <= UREG_I7; i++)
325                 err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]);
326         if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
327                 err |= __get_user(i, &sf->v8plus.g_upper[0]);
328                 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
329                         unsigned long asi;
330 
331                         for (i = UREG_G1; i <= UREG_I7; i++)
332                                 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
333                         err |= __get_user(asi, &sf->v8plus.asi);
334                         regs->tstate &= ~TSTATE_ASI;
335                         regs->tstate |= ((asi & 0xffUL) << 24UL);
336                 }
337         }
338 
339         /* User can only change condition codes in %tstate. */
340         regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
341         regs->tstate |= psr_to_tstate_icc(psr);
342 
343         /* Prevent syscall restart.  */
344         pt_regs_clear_syscall(regs);
345 
346         err |= __get_user(fpu_save, &sf->fpu_save);
347         if (!err && fpu_save)
348                 err |= restore_fpu_state(regs, compat_ptr(fpu_save));
349         err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
350         err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
351         st.ss_sp = compat_ptr(u_ss_sp);
352         err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
353         err |= __get_user(st.ss_size, &sf->stack.ss_size);
354         if (err)
355                 goto segv;
356                 
357         /* It is more difficult to avoid calling this function than to
358            call it and ignore errors.  */
359         old_fs = get_fs();
360         set_fs(KERNEL_DS);
361         do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
362         set_fs(old_fs);
363         
364         err |= __get_user(rwin_save, &sf->rwin_save);
365         if (!err && rwin_save) {
366                 if (restore_rwin_state(compat_ptr(rwin_save)))
367                         goto segv;
368         }
369 
370         switch (_NSIG_WORDS) {
371                 case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
372                 case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
373                 case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
374                 case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
375         }
376         set_current_blocked(&set);
377         return;
378 segv:
379         force_sig(SIGSEGV, current);
380 }
381 
382 /* Checks if the fp is valid */
383 static int invalid_frame_pointer(void __user *fp, int fplen)
384 {
385         if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
386                 return 1;
387         return 0;
388 }
389 
390 static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
391 {
392         unsigned long sp;
393         
394         regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
395         sp = regs->u_regs[UREG_FP];
396         
397         /*
398          * If we are on the alternate signal stack and would overflow it, don't.
399          * Return an always-bogus address instead so we will die with SIGSEGV.
400          */
401         if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
402                 return (void __user *) -1L;
403 
404         /* This is the X/Open sanctioned signal stack switching.  */
405         if (sa->sa_flags & SA_ONSTACK) {
406                 if (sas_ss_flags(sp) == 0)
407                         sp = current->sas_ss_sp + current->sas_ss_size;
408         }
409 
410         sp -= framesize;
411 
412         /* Always align the stack frame.  This handles two cases.  First,
413          * sigaltstack need not be mindful of platform specific stack
414          * alignment.  Second, if we took this signal because the stack
415          * is not aligned properly, we'd like to take the signal cleanly
416          * and report that.
417          */
418         sp &= ~15UL;
419 
420         return (void __user *) sp;
421 }
422 
423 /* The I-cache flush instruction only works in the primary ASI, which
424  * right now is the nucleus, aka. kernel space.
425  *
426  * Therefore we have to kick the instructions out using the kernel
427  * side linear mapping of the physical address backing the user
428  * instructions.
429  */
430 static void flush_signal_insns(unsigned long address)
431 {
432         unsigned long pstate, paddr;
433         pte_t *ptep, pte;
434         pgd_t *pgdp;
435         pud_t *pudp;
436         pmd_t *pmdp;
437 
438         /* Commit all stores of the instructions we are about to flush.  */
439         wmb();
440 
441         /* Disable cross-call reception.  In this way even a very wide
442          * munmap() on another cpu can't tear down the page table
443          * hierarchy from underneath us, since that can't complete
444          * until the IPI tlb flush returns.
445          */
446 
447         __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
448         __asm__ __volatile__("wrpr %0, %1, %%pstate"
449                                 : : "r" (pstate), "i" (PSTATE_IE));
450 
451         pgdp = pgd_offset(current->mm, address);
452         if (pgd_none(*pgdp))
453                 goto out_irqs_on;
454         pudp = pud_offset(pgdp, address);
455         if (pud_none(*pudp))
456                 goto out_irqs_on;
457         pmdp = pmd_offset(pudp, address);
458         if (pmd_none(*pmdp))
459                 goto out_irqs_on;
460 
461         ptep = pte_offset_map(pmdp, address);
462         pte = *ptep;
463         if (!pte_present(pte))
464                 goto out_unmap;
465 
466         paddr = (unsigned long) page_address(pte_page(pte));
467 
468         __asm__ __volatile__("flush     %0 + %1"
469                              : /* no outputs */
470                              : "r" (paddr),
471                                "r" (address & (PAGE_SIZE - 1))
472                              : "memory");
473 
474 out_unmap:
475         pte_unmap(ptep);
476 out_irqs_on:
477         __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
478 
479 }
480 
481 static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
482                          int signo, sigset_t *oldset)
483 {
484         struct signal_frame32 __user *sf;
485         int i, err, wsaved;
486         void __user *tail;
487         int sigframe_size;
488         u32 psr;
489         unsigned int seta[_COMPAT_NSIG_WORDS];
490 
491         /* 1. Make sure everything is clean */
492         synchronize_user_stack();
493         save_and_clear_fpu();
494         
495         wsaved = get_thread_wsaved();
496 
497         sigframe_size = sizeof(*sf);
498         if (current_thread_info()->fpsaved[0] & FPRS_FEF)
499                 sigframe_size += sizeof(__siginfo_fpu_t);
500         if (wsaved)
501                 sigframe_size += sizeof(__siginfo_rwin_t);
502 
503         sf = (struct signal_frame32 __user *)
504                 get_sigframe(&ka->sa, regs, sigframe_size);
505         
506         if (invalid_frame_pointer(sf, sigframe_size))
507                 goto sigill;
508 
509         tail = (sf + 1);
510 
511         /* 2. Save the current process state */
512         if (test_thread_flag(TIF_32BIT)) {
513                 regs->tpc &= 0xffffffff;
514                 regs->tnpc &= 0xffffffff;
515         }
516         err  = put_user(regs->tpc, &sf->info.si_regs.pc);
517         err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
518         err |= __put_user(regs->y, &sf->info.si_regs.y);
519         psr = tstate_to_psr(regs->tstate);
520         if (current_thread_info()->fpsaved[0] & FPRS_FEF)
521                 psr |= PSR_EF;
522         err |= __put_user(psr, &sf->info.si_regs.psr);
523         for (i = 0; i < 16; i++)
524                 err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
525         err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
526         err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
527         for (i = 1; i < 16; i++)
528                 err |= __put_user(((u32 *)regs->u_regs)[2*i],
529                                   &sf->v8plus.g_upper[i]);
530         err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
531                           &sf->v8plus.asi);
532 
533         if (psr & PSR_EF) {
534                 __siginfo_fpu_t __user *fp = tail;
535                 tail += sizeof(*fp);
536                 err |= save_fpu_state(regs, fp);
537                 err |= __put_user((u64)fp, &sf->fpu_save);
538         } else {
539                 err |= __put_user(0, &sf->fpu_save);
540         }
541         if (wsaved) {
542                 __siginfo_rwin_t __user *rwp = tail;
543                 tail += sizeof(*rwp);
544                 err |= save_rwin_state(wsaved, rwp);
545                 err |= __put_user((u64)rwp, &sf->rwin_save);
546                 set_thread_wsaved(0);
547         } else {
548                 err |= __put_user(0, &sf->rwin_save);
549         }
550 
551         switch (_NSIG_WORDS) {
552         case 4: seta[7] = (oldset->sig[3] >> 32);
553                 seta[6] = oldset->sig[3];
554         case 3: seta[5] = (oldset->sig[2] >> 32);
555                 seta[4] = oldset->sig[2];
556         case 2: seta[3] = (oldset->sig[1] >> 32);
557                 seta[2] = oldset->sig[1];
558         case 1: seta[1] = (oldset->sig[0] >> 32);
559                 seta[0] = oldset->sig[0];
560         }
561         err |= __put_user(seta[0], &sf->info.si_mask);
562         err |= __copy_to_user(sf->extramask, seta + 1,
563                               (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
564 
565         if (!wsaved) {
566                 err |= copy_in_user((u32 __user *)sf,
567                                     (u32 __user *)(regs->u_regs[UREG_FP]),
568                                     sizeof(struct reg_window32));
569         } else {
570                 struct reg_window *rp;
571 
572                 rp = &current_thread_info()->reg_window[wsaved - 1];
573                 for (i = 0; i < 8; i++)
574                         err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
575                 for (i = 0; i < 6; i++)
576                         err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
577                 err |= __put_user(rp->ins[6], &sf->ss.fp);
578                 err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
579         }       
580         if (err)
581                 goto sigsegv;
582 
583         /* 3. signal handler back-trampoline and parameters */
584         regs->u_regs[UREG_FP] = (unsigned long) sf;
585         regs->u_regs[UREG_I0] = signo;
586         regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
587         regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
588 
589         /* 4. signal handler */
590         regs->tpc = (unsigned long) ka->sa.sa_handler;
591         regs->tnpc = (regs->tpc + 4);
592         if (test_thread_flag(TIF_32BIT)) {
593                 regs->tpc &= 0xffffffff;
594                 regs->tnpc &= 0xffffffff;
595         }
596 
597         /* 5. return to kernel instructions */
598         if (ka->ka_restorer) {
599                 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
600         } else {
601                 unsigned long address = ((unsigned long)&(sf->insns[0]));
602 
603                 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
604         
605                 err  = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
606                 err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
607                 if (err)
608                         goto sigsegv;
609                 flush_signal_insns(address);
610         }
611         return 0;
612 
613 sigill:
614         do_exit(SIGILL);
615         return -EINVAL;
616 
617 sigsegv:
618         force_sigsegv(signo, current);
619         return -EFAULT;
620 }
621 
622 static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
623                             unsigned long signr, sigset_t *oldset,
624                             siginfo_t *info)
625 {
626         struct rt_signal_frame32 __user *sf;
627         int i, err, wsaved;
628         void __user *tail;
629         int sigframe_size;
630         u32 psr;
631         compat_sigset_t seta;
632 
633         /* 1. Make sure everything is clean */
634         synchronize_user_stack();
635         save_and_clear_fpu();
636         
637         wsaved = get_thread_wsaved();
638 
639         sigframe_size = sizeof(*sf);
640         if (current_thread_info()->fpsaved[0] & FPRS_FEF)
641                 sigframe_size += sizeof(__siginfo_fpu_t);
642         if (wsaved)
643                 sigframe_size += sizeof(__siginfo_rwin_t);
644 
645         sf = (struct rt_signal_frame32 __user *)
646                 get_sigframe(&ka->sa, regs, sigframe_size);
647         
648         if (invalid_frame_pointer(sf, sigframe_size))
649                 goto sigill;
650 
651         tail = (sf + 1);
652 
653         /* 2. Save the current process state */
654         if (test_thread_flag(TIF_32BIT)) {
655                 regs->tpc &= 0xffffffff;
656                 regs->tnpc &= 0xffffffff;
657         }
658         err  = put_user(regs->tpc, &sf->regs.pc);
659         err |= __put_user(regs->tnpc, &sf->regs.npc);
660         err |= __put_user(regs->y, &sf->regs.y);
661         psr = tstate_to_psr(regs->tstate);
662         if (current_thread_info()->fpsaved[0] & FPRS_FEF)
663                 psr |= PSR_EF;
664         err |= __put_user(psr, &sf->regs.psr);
665         for (i = 0; i < 16; i++)
666                 err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
667         err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
668         err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
669         for (i = 1; i < 16; i++)
670                 err |= __put_user(((u32 *)regs->u_regs)[2*i],
671                                   &sf->v8plus.g_upper[i]);
672         err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
673                           &sf->v8plus.asi);
674 
675         if (psr & PSR_EF) {
676                 __siginfo_fpu_t __user *fp = tail;
677                 tail += sizeof(*fp);
678                 err |= save_fpu_state(regs, fp);
679                 err |= __put_user((u64)fp, &sf->fpu_save);
680         } else {
681                 err |= __put_user(0, &sf->fpu_save);
682         }
683         if (wsaved) {
684                 __siginfo_rwin_t __user *rwp = tail;
685                 tail += sizeof(*rwp);
686                 err |= save_rwin_state(wsaved, rwp);
687                 err |= __put_user((u64)rwp, &sf->rwin_save);
688                 set_thread_wsaved(0);
689         } else {
690                 err |= __put_user(0, &sf->rwin_save);
691         }
692 
693         /* Update the siginfo structure.  */
694         err |= copy_siginfo_to_user32(&sf->info, info);
695         
696         /* Setup sigaltstack */
697         err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
698         err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
699         err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
700 
701         switch (_NSIG_WORDS) {
702         case 4: seta.sig[7] = (oldset->sig[3] >> 32);
703                 seta.sig[6] = oldset->sig[3];
704         case 3: seta.sig[5] = (oldset->sig[2] >> 32);
705                 seta.sig[4] = oldset->sig[2];
706         case 2: seta.sig[3] = (oldset->sig[1] >> 32);
707                 seta.sig[2] = oldset->sig[1];
708         case 1: seta.sig[1] = (oldset->sig[0] >> 32);
709                 seta.sig[0] = oldset->sig[0];
710         }
711         err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
712 
713         if (!wsaved) {
714                 err |= copy_in_user((u32 __user *)sf,
715                                     (u32 __user *)(regs->u_regs[UREG_FP]),
716                                     sizeof(struct reg_window32));
717         } else {
718                 struct reg_window *rp;
719 
720                 rp = &current_thread_info()->reg_window[wsaved - 1];
721                 for (i = 0; i < 8; i++)
722                         err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
723                 for (i = 0; i < 6; i++)
724                         err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
725                 err |= __put_user(rp->ins[6], &sf->ss.fp);
726                 err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
727         }
728         if (err)
729                 goto sigsegv;
730         
731         /* 3. signal handler back-trampoline and parameters */
732         regs->u_regs[UREG_FP] = (unsigned long) sf;
733         regs->u_regs[UREG_I0] = signr;
734         regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
735         regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
736 
737         /* 4. signal handler */
738         regs->tpc = (unsigned long) ka->sa.sa_handler;
739         regs->tnpc = (regs->tpc + 4);
740         if (test_thread_flag(TIF_32BIT)) {
741                 regs->tpc &= 0xffffffff;
742                 regs->tnpc &= 0xffffffff;
743         }
744 
745         /* 5. return to kernel instructions */
746         if (ka->ka_restorer)
747                 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
748         else {
749                 unsigned long address = ((unsigned long)&(sf->insns[0]));
750 
751                 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
752         
753                 /* mov __NR_rt_sigreturn, %g1 */
754                 err |= __put_user(0x82102065, &sf->insns[0]);
755 
756                 /* t 0x10 */
757                 err |= __put_user(0x91d02010, &sf->insns[1]);
758                 if (err)
759                         goto sigsegv;
760 
761                 flush_signal_insns(address);
762         }
763         return 0;
764 
765 sigill:
766         do_exit(SIGILL);
767         return -EINVAL;
768 
769 sigsegv:
770         force_sigsegv(signr, current);
771         return -EFAULT;
772 }
773 
774 static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
775                                   siginfo_t *info,
776                                   sigset_t *oldset, struct pt_regs *regs)
777 {
778         int err;
779 
780         if (ka->sa.sa_flags & SA_SIGINFO)
781                 err = setup_rt_frame32(ka, regs, signr, oldset, info);
782         else
783                 err = setup_frame32(ka, regs, signr, oldset);
784 
785         if (err)
786                 return;
787 
788         signal_delivered(signr, info, ka, regs, 0);
789 }
790 
791 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
792                                      struct sigaction *sa)
793 {
794         switch (regs->u_regs[UREG_I0]) {
795         case ERESTART_RESTARTBLOCK:
796         case ERESTARTNOHAND:
797         no_system_call_restart:
798                 regs->u_regs[UREG_I0] = EINTR;
799                 regs->tstate |= TSTATE_ICARRY;
800                 break;
801         case ERESTARTSYS:
802                 if (!(sa->sa_flags & SA_RESTART))
803                         goto no_system_call_restart;
804                 /* fallthrough */
805         case ERESTARTNOINTR:
806                 regs->u_regs[UREG_I0] = orig_i0;
807                 regs->tpc -= 4;
808                 regs->tnpc -= 4;
809         }
810 }
811 
812 /* Note that 'init' is a special process: it doesn't get signals it doesn't
813  * want to handle. Thus you cannot kill init even with a SIGKILL even by
814  * mistake.
815  */
816 void do_signal32(sigset_t *oldset, struct pt_regs * regs)
817 {
818         struct k_sigaction ka;
819         unsigned long orig_i0;
820         int restart_syscall;
821         siginfo_t info;
822         int signr;
823         
824         signr = get_signal_to_deliver(&info, &ka, regs, NULL);
825 
826         restart_syscall = 0;
827         orig_i0 = 0;
828         if (pt_regs_is_syscall(regs) &&
829             (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
830                 restart_syscall = 1;
831                 orig_i0 = regs->u_regs[UREG_G6];
832         }
833 
834         if (signr > 0) {
835                 if (restart_syscall)
836                         syscall_restart32(orig_i0, regs, &ka.sa);
837                 handle_signal32(signr, &ka, &info, oldset, regs);
838                 return;
839         }
840         if (restart_syscall &&
841             (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
842              regs->u_regs[UREG_I0] == ERESTARTSYS ||
843              regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
844                 /* replay the system call when we are done */
845                 regs->u_regs[UREG_I0] = orig_i0;
846                 regs->tpc -= 4;
847                 regs->tnpc -= 4;
848                 pt_regs_clear_syscall(regs);
849         }
850         if (restart_syscall &&
851             regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
852                 regs->u_regs[UREG_G1] = __NR_restart_syscall;
853                 regs->tpc -= 4;
854                 regs->tnpc -= 4;
855                 pt_regs_clear_syscall(regs);
856         }
857 
858         /* If there's no signal to deliver, we just put the saved sigmask
859          * back
860          */
861         restore_saved_sigmask();
862 }
863 
864 struct sigstack32 {
865         u32 the_stack;
866         int cur_status;
867 };
868 
869 asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
870 {
871         struct sigstack32 __user *ssptr =
872                 (struct sigstack32 __user *)((unsigned long)(u_ssptr));
873         struct sigstack32 __user *ossptr =
874                 (struct sigstack32 __user *)((unsigned long)(u_ossptr));
875         int ret = -EFAULT;
876 
877         /* First see if old state is wanted. */
878         if (ossptr) {
879                 if (put_user(current->sas_ss_sp + current->sas_ss_size,
880                              &ossptr->the_stack) ||
881                     __put_user(on_sig_stack(sp), &ossptr->cur_status))
882                         goto out;
883         }
884         
885         /* Now see if we want to update the new state. */
886         if (ssptr) {
887                 u32 ss_sp;
888 
889                 if (get_user(ss_sp, &ssptr->the_stack))
890                         goto out;
891 
892                 /* If the current stack was set with sigaltstack, don't
893                  * swap stacks while we are on it.
894                  */
895                 ret = -EPERM;
896                 if (current->sas_ss_sp && on_sig_stack(sp))
897                         goto out;
898                         
899                 /* Since we don't know the extent of the stack, and we don't
900                  * track onstack-ness, but rather calculate it, we must
901                  * presume a size.  Ho hum this interface is lossy.
902                  */
903                 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
904                 current->sas_ss_size = SIGSTKSZ;
905         }
906         
907         ret = 0;
908 out:
909         return ret;
910 }
911 
912 asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
913 {
914         stack_t uss, uoss;
915         u32 u_ss_sp = 0;
916         int ret;
917         mm_segment_t old_fs;
918         stack_t32 __user *uss32 = compat_ptr(ussa);
919         stack_t32 __user *uoss32 = compat_ptr(uossa);
920         
921         if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
922                     __get_user(uss.ss_flags, &uss32->ss_flags) ||
923                     __get_user(uss.ss_size, &uss32->ss_size)))
924                 return -EFAULT;
925         uss.ss_sp = compat_ptr(u_ss_sp);
926         old_fs = get_fs();
927         set_fs(KERNEL_DS);
928         ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
929                              uossa ? (stack_t __user *) &uoss : NULL, sp);
930         set_fs(old_fs);
931         if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
932                     __put_user(uoss.ss_flags, &uoss32->ss_flags) ||
933                     __put_user(uoss.ss_size, &uoss32->ss_size)))
934                 return -EFAULT;
935         return ret;
936 }
937 

~ [ 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