x86: Remove stale pmtimer_64.c
[pandora-kernel.git] / arch / tile / kernel / compat_signal.c
1 /*
2  * Copyright 2010 Tilera Corporation. All Rights Reserved.
3  *
4  *   This program is free software; you can redistribute it and/or
5  *   modify it under the terms of the GNU General Public License
6  *   as published by the Free Software Foundation, version 2.
7  *
8  *   This program is distributed in the hope that it will be useful, but
9  *   WITHOUT ANY WARRANTY; without even the implied warranty of
10  *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11  *   NON INFRINGEMENT.  See the GNU General Public License for
12  *   more details.
13  */
14
15 #include <linux/sched.h>
16 #include <linux/mm.h>
17 #include <linux/smp.h>
18 #include <linux/smp_lock.h>
19 #include <linux/kernel.h>
20 #include <linux/signal.h>
21 #include <linux/errno.h>
22 #include <linux/wait.h>
23 #include <linux/unistd.h>
24 #include <linux/stddef.h>
25 #include <linux/personality.h>
26 #include <linux/suspend.h>
27 #include <linux/ptrace.h>
28 #include <linux/elf.h>
29 #include <linux/compat.h>
30 #include <linux/syscalls.h>
31 #include <linux/uaccess.h>
32 #include <asm/processor.h>
33 #include <asm/ucontext.h>
34 #include <asm/sigframe.h>
35 #include <asm/syscalls.h>
36 #include <arch/interrupts.h>
37
38 struct compat_sigaction {
39         compat_uptr_t sa_handler;
40         compat_ulong_t sa_flags;
41         compat_uptr_t sa_restorer;
42         sigset_t sa_mask __packed;
43 };
44
45 struct compat_sigaltstack {
46         compat_uptr_t ss_sp;
47         int ss_flags;
48         compat_size_t ss_size;
49 };
50
51 struct compat_ucontext {
52         compat_ulong_t    uc_flags;
53         compat_uptr_t     uc_link;
54         struct compat_sigaltstack         uc_stack;
55         struct sigcontext uc_mcontext;
56         sigset_t          uc_sigmask;   /* mask last for extensibility */
57 };
58
59 struct compat_siginfo {
60         int si_signo;
61         int si_errno;
62         int si_code;
63
64         union {
65                 int _pad[SI_PAD_SIZE];
66
67                 /* kill() */
68                 struct {
69                         unsigned int _pid;      /* sender's pid */
70                         unsigned int _uid;      /* sender's uid */
71                 } _kill;
72
73                 /* POSIX.1b timers */
74                 struct {
75                         compat_timer_t _tid;    /* timer id */
76                         int _overrun;           /* overrun count */
77                         compat_sigval_t _sigval;        /* same as below */
78                         int _sys_private;       /* not to be passed to user */
79                         int _overrun_incr;      /* amount to add to overrun */
80                 } _timer;
81
82                 /* POSIX.1b signals */
83                 struct {
84                         unsigned int _pid;      /* sender's pid */
85                         unsigned int _uid;      /* sender's uid */
86                         compat_sigval_t _sigval;
87                 } _rt;
88
89                 /* SIGCHLD */
90                 struct {
91                         unsigned int _pid;      /* which child */
92                         unsigned int _uid;      /* sender's uid */
93                         int _status;            /* exit code */
94                         compat_clock_t _utime;
95                         compat_clock_t _stime;
96                 } _sigchld;
97
98                 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
99                 struct {
100                         unsigned int _addr;     /* faulting insn/memory ref. */
101 #ifdef __ARCH_SI_TRAPNO
102                         int _trapno;    /* TRAP # which caused the signal */
103 #endif
104                 } _sigfault;
105
106                 /* SIGPOLL */
107                 struct {
108                         int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
109                         int _fd;
110                 } _sigpoll;
111         } _sifields;
112 };
113
114 struct compat_rt_sigframe {
115         unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
116         struct compat_siginfo info;
117         struct compat_ucontext uc;
118 };
119
120 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
121
122 long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
123                              struct compat_sigaction __user *oact,
124                              size_t sigsetsize)
125 {
126         struct k_sigaction new_sa, old_sa;
127         int ret = -EINVAL;
128
129         /* XXX: Don't preclude handling different sized sigset_t's.  */
130         if (sigsetsize != sizeof(sigset_t))
131                 goto out;
132
133         if (act) {
134                 compat_uptr_t handler, restorer;
135
136                 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
137                     __get_user(handler, &act->sa_handler) ||
138                     __get_user(new_sa.sa.sa_flags, &act->sa_flags) ||
139                     __get_user(restorer, &act->sa_restorer) ||
140                     __copy_from_user(&new_sa.sa.sa_mask, &act->sa_mask,
141                                      sizeof(sigset_t)))
142                         return -EFAULT;
143                 new_sa.sa.sa_handler = compat_ptr(handler);
144                 new_sa.sa.sa_restorer = compat_ptr(restorer);
145         }
146
147         ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
148
149         if (!ret && oact) {
150                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
151                     __put_user(ptr_to_compat(old_sa.sa.sa_handler),
152                                &oact->sa_handler) ||
153                     __put_user(ptr_to_compat(old_sa.sa.sa_restorer),
154                                &oact->sa_restorer) ||
155                     __put_user(old_sa.sa.sa_flags, &oact->sa_flags) ||
156                     __copy_to_user(&oact->sa_mask, &old_sa.sa.sa_mask,
157                                    sizeof(sigset_t)))
158                         return -EFAULT;
159         }
160 out:
161         return ret;
162 }
163
164 long compat_sys_rt_sigqueueinfo(int pid, int sig,
165                                 struct compat_siginfo __user *uinfo)
166 {
167         siginfo_t info;
168         int ret;
169         mm_segment_t old_fs = get_fs();
170
171         if (copy_siginfo_from_user32(&info, uinfo))
172                 return -EFAULT;
173         set_fs(KERNEL_DS);
174         ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *)&info);
175         set_fs(old_fs);
176         return ret;
177 }
178
179 int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from)
180 {
181         int err;
182
183         if (!access_ok(VERIFY_WRITE, to, sizeof(struct compat_siginfo)))
184                 return -EFAULT;
185
186         /* If you change siginfo_t structure, please make sure that
187            this code is fixed accordingly.
188            It should never copy any pad contained in the structure
189            to avoid security leaks, but must copy the generic
190            3 ints plus the relevant union member.  */
191         err = __put_user(from->si_signo, &to->si_signo);
192         err |= __put_user(from->si_errno, &to->si_errno);
193         err |= __put_user((short)from->si_code, &to->si_code);
194
195         if (from->si_code < 0) {
196                 err |= __put_user(from->si_pid, &to->si_pid);
197                 err |= __put_user(from->si_uid, &to->si_uid);
198                 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
199         } else {
200                 /*
201                  * First 32bits of unions are always present:
202                  * si_pid === si_band === si_tid === si_addr(LS half)
203                  */
204                 err |= __put_user(from->_sifields._pad[0],
205                                   &to->_sifields._pad[0]);
206                 switch (from->si_code >> 16) {
207                 case __SI_FAULT >> 16:
208                         break;
209                 case __SI_CHLD >> 16:
210                         err |= __put_user(from->si_utime, &to->si_utime);
211                         err |= __put_user(from->si_stime, &to->si_stime);
212                         err |= __put_user(from->si_status, &to->si_status);
213                         /* FALL THROUGH */
214                 default:
215                 case __SI_KILL >> 16:
216                         err |= __put_user(from->si_uid, &to->si_uid);
217                         break;
218                 case __SI_POLL >> 16:
219                         err |= __put_user(from->si_fd, &to->si_fd);
220                         break;
221                 case __SI_TIMER >> 16:
222                         err |= __put_user(from->si_overrun, &to->si_overrun);
223                         err |= __put_user(ptr_to_compat(from->si_ptr),
224                                           &to->si_ptr);
225                         break;
226                          /* This is not generated by the kernel as of now.  */
227                 case __SI_RT >> 16:
228                 case __SI_MESGQ >> 16:
229                         err |= __put_user(from->si_uid, &to->si_uid);
230                         err |= __put_user(from->si_int, &to->si_int);
231                         break;
232                 }
233         }
234         return err;
235 }
236
237 int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
238 {
239         int err;
240         u32 ptr32;
241
242         if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
243                 return -EFAULT;
244
245         err = __get_user(to->si_signo, &from->si_signo);
246         err |= __get_user(to->si_errno, &from->si_errno);
247         err |= __get_user(to->si_code, &from->si_code);
248
249         err |= __get_user(to->si_pid, &from->si_pid);
250         err |= __get_user(to->si_uid, &from->si_uid);
251         err |= __get_user(ptr32, &from->si_ptr);
252         to->si_ptr = compat_ptr(ptr32);
253
254         return err;
255 }
256
257 long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
258                              struct compat_sigaltstack __user *uoss_ptr,
259                              struct pt_regs *regs)
260 {
261         stack_t uss, uoss;
262         int ret;
263         mm_segment_t seg;
264
265         if (uss_ptr) {
266                 u32 ptr;
267
268                 memset(&uss, 0, sizeof(stack_t));
269                 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)) ||
270                             __get_user(ptr, &uss_ptr->ss_sp) ||
271                             __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
272                             __get_user(uss.ss_size, &uss_ptr->ss_size))
273                         return -EFAULT;
274                 uss.ss_sp = compat_ptr(ptr);
275         }
276         seg = get_fs();
277         set_fs(KERNEL_DS);
278         ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL,
279                              (stack_t __user __force *)&uoss,
280                              (unsigned long)compat_ptr(regs->sp));
281         set_fs(seg);
282         if (ret >= 0 && uoss_ptr)  {
283                 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) ||
284                     __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
285                     __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
286                     __put_user(uoss.ss_size, &uoss_ptr->ss_size))
287                         ret = -EFAULT;
288         }
289         return ret;
290 }
291
292 long _compat_sys_rt_sigreturn(struct pt_regs *regs)
293 {
294         struct compat_rt_sigframe __user *frame =
295                 (struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
296         sigset_t set;
297         long r0;
298
299         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
300                 goto badframe;
301         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
302                 goto badframe;
303
304         sigdelsetmask(&set, ~_BLOCKABLE);
305         spin_lock_irq(&current->sighand->siglock);
306         current->blocked = set;
307         recalc_sigpending();
308         spin_unlock_irq(&current->sighand->siglock);
309
310         if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
311                 goto badframe;
312
313         if (_compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
314                 goto badframe;
315
316         return r0;
317
318 badframe:
319         force_sig(SIGSEGV, current);
320         return 0;
321 }
322
323 /*
324  * Determine which stack to use..
325  */
326 static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
327                                                struct pt_regs *regs,
328                                                size_t frame_size)
329 {
330         unsigned long sp;
331
332         /* Default to using normal stack */
333         sp = (unsigned long)compat_ptr(regs->sp);
334
335         /*
336          * If we are on the alternate signal stack and would overflow
337          * it, don't.  Return an always-bogus address instead so we
338          * will die with SIGSEGV.
339          */
340         if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
341                 return (void __user __force *)-1UL;
342
343         /* This is the X/Open sanctioned signal stack switching.  */
344         if (ka->sa.sa_flags & SA_ONSTACK) {
345                 if (sas_ss_flags(sp) == 0)
346                         sp = current->sas_ss_sp + current->sas_ss_size;
347         }
348
349         sp -= frame_size;
350         /*
351          * Align the stack pointer according to the TILE ABI,
352          * i.e. so that on function entry (sp & 15) == 0.
353          */
354         sp &= -16UL;
355         return (void __user *) sp;
356 }
357
358 int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
359                           sigset_t *set, struct pt_regs *regs)
360 {
361         unsigned long restorer;
362         struct compat_rt_sigframe __user *frame;
363         int err = 0;
364         int usig;
365
366         frame = compat_get_sigframe(ka, regs, sizeof(*frame));
367
368         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
369                 goto give_sigsegv;
370
371         usig = current_thread_info()->exec_domain
372                 && current_thread_info()->exec_domain->signal_invmap
373                 && sig < 32
374                 ? current_thread_info()->exec_domain->signal_invmap[sig]
375                 : sig;
376
377         /* Always write at least the signal number for the stack backtracer. */
378         if (ka->sa.sa_flags & SA_SIGINFO) {
379                 /* At sigreturn time, restore the callee-save registers too. */
380                 err |= copy_siginfo_to_user32(&frame->info, info);
381                 regs->flags |= PT_FLAGS_RESTORE_REGS;
382         } else {
383                 err |= __put_user(info->si_signo, &frame->info.si_signo);
384         }
385
386         /* Create the ucontext.  */
387         err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
388         err |= __put_user(0, &frame->uc.uc_flags);
389         err |= __put_user(0, &frame->uc.uc_link);
390         err |= __put_user(ptr_to_compat((void *)(current->sas_ss_sp)),
391                           &frame->uc.uc_stack.ss_sp);
392         err |= __put_user(sas_ss_flags(regs->sp),
393                           &frame->uc.uc_stack.ss_flags);
394         err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
395         err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
396         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
397         if (err)
398                 goto give_sigsegv;
399
400         restorer = VDSO_BASE;
401         if (ka->sa.sa_flags & SA_RESTORER)
402                 restorer = ptr_to_compat_reg(ka->sa.sa_restorer);
403
404         /*
405          * Set up registers for signal handler.
406          * Registers that we don't modify keep the value they had from
407          * user-space at the time we took the signal.
408          */
409         regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
410         regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
411         regs->sp = ptr_to_compat_reg(frame);
412         regs->lr = restorer;
413         regs->regs[0] = (unsigned long) usig;
414
415         if (ka->sa.sa_flags & SA_SIGINFO) {
416                 /* Need extra arguments, so mark to restore caller-saves. */
417                 regs->regs[1] = ptr_to_compat_reg(&frame->info);
418                 regs->regs[2] = ptr_to_compat_reg(&frame->uc);
419                 regs->flags |= PT_FLAGS_CALLER_SAVES;
420         }
421
422         /*
423          * Notify any tracer that was single-stepping it.
424          * The tracer may want to single-step inside the
425          * handler too.
426          */
427         if (test_thread_flag(TIF_SINGLESTEP))
428                 ptrace_notify(SIGTRAP);
429
430         return 0;
431
432 give_sigsegv:
433         force_sigsegv(sig, current);
434         return -EFAULT;
435 }