Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
signal.c
Go to the documentation of this file.
1 /*
2  * Port on Texas Instruments TMS320C6x architecture
3  *
4  * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
5  * Author: Aurelien Jacquiot ([email protected])
6  *
7  * Updated for 2.6.34: Mark Salter <[email protected]>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/uaccess.h>
16 #include <linux/syscalls.h>
17 #include <linux/tracehook.h>
18 
19 #include <asm/ucontext.h>
20 #include <asm/cacheflush.h>
21 
22 
23 /*
24  * Do a signal return, undo the signal stack.
25  */
26 
27 #define RETCODE_SIZE (9 << 2) /* 9 instructions = 36 bytes */
28 
29 struct rt_sigframe {
30  struct siginfo __user *pinfo;
31  void __user *puc;
32  struct siginfo info;
33  struct ucontext uc;
34  unsigned long retcode[RETCODE_SIZE >> 2];
35 };
36 
37 static int restore_sigcontext(struct pt_regs *regs,
38  struct sigcontext __user *sc)
39 {
40  int err = 0;
41 
42  /* The access_ok check was done by caller, so use __get_user here */
43 #define COPY(x) (err |= __get_user(regs->x, &sc->sc_##x))
44 
45  COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8);
46  COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9);
47  COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9);
48 
49  COPY(a16); COPY(a17); COPY(a18); COPY(a19);
50  COPY(a20); COPY(a21); COPY(a22); COPY(a23);
51  COPY(a24); COPY(a25); COPY(a26); COPY(a27);
52  COPY(a28); COPY(a29); COPY(a30); COPY(a31);
53  COPY(b16); COPY(b17); COPY(b18); COPY(b19);
54  COPY(b20); COPY(b21); COPY(b22); COPY(b23);
55  COPY(b24); COPY(b25); COPY(b26); COPY(b27);
56  COPY(b28); COPY(b29); COPY(b30); COPY(b31);
57 
58  COPY(csr); COPY(pc);
59 
60 #undef COPY
61 
62  return err;
63 }
64 
66 {
67  struct rt_sigframe __user *frame;
68  sigset_t set;
69 
70  /* Always make any pending restarted system calls return -EINTR */
71  current_thread_info()->restart_block.fn = do_no_restart_syscall;
72 
73  /*
74  * Since we stacked the signal on a dword boundary,
75  * 'sp' should be dword aligned here. If it's
76  * not, then the user is trying to mess with us.
77  */
78  if (regs->sp & 7)
79  goto badframe;
80 
81  frame = (struct rt_sigframe __user *) ((unsigned long) regs->sp + 8);
82 
83  if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
84  goto badframe;
85  if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
86  goto badframe;
87 
88  set_current_blocked(&set);
89 
90  if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
91  goto badframe;
92 
93  return regs->a4;
94 
95 badframe:
97  return 0;
98 }
99 
100 static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
101  unsigned long mask)
102 {
103  int err = 0;
104 
105  err |= __put_user(mask, &sc->sc_mask);
106 
107  /* The access_ok check was done by caller, so use __put_user here */
108 #define COPY(x) (err |= __put_user(regs->x, &sc->sc_##x))
109 
110  COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8);
111  COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9);
112  COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9);
113 
114  COPY(a16); COPY(a17); COPY(a18); COPY(a19);
115  COPY(a20); COPY(a21); COPY(a22); COPY(a23);
116  COPY(a24); COPY(a25); COPY(a26); COPY(a27);
117  COPY(a28); COPY(a29); COPY(a30); COPY(a31);
118  COPY(b16); COPY(b17); COPY(b18); COPY(b19);
119  COPY(b20); COPY(b21); COPY(b22); COPY(b23);
120  COPY(b24); COPY(b25); COPY(b26); COPY(b27);
121  COPY(b28); COPY(b29); COPY(b30); COPY(b31);
122 
123  COPY(csr); COPY(pc);
124 
125 #undef COPY
126 
127  return err;
128 }
129 
130 static inline void __user *get_sigframe(struct k_sigaction *ka,
131  struct pt_regs *regs,
132  unsigned long framesize)
133 {
134  unsigned long sp = regs->sp;
135 
136  /*
137  * This is the X/Open sanctioned signal stack switching.
138  */
139  if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp) == 0)
140  sp = current->sas_ss_sp + current->sas_ss_size;
141 
142  /*
143  * No matter what happens, 'sp' must be dword
144  * aligned. Otherwise, nasty things will happen
145  */
146  return (void __user *)((sp - framesize) & ~7);
147 }
148 
149 static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
150  sigset_t *set, struct pt_regs *regs)
151 {
152  struct rt_sigframe __user *frame;
153  unsigned long __user *retcode;
154  int err = 0;
155 
156  frame = get_sigframe(ka, regs, sizeof(*frame));
157 
158  if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
159  goto segv_and_exit;
160 
161  err |= __put_user(&frame->info, &frame->pinfo);
162  err |= __put_user(&frame->uc, &frame->puc);
163  err |= copy_siginfo_to_user(&frame->info, info);
164 
165  /* Clear all the bits of the ucontext we don't use. */
166  err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
167 
168  err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
169  err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
170 
171  /* Set up to return from userspace */
172  retcode = (unsigned long __user *) &frame->retcode;
173 
174  /* The access_ok check was done above, so use __put_user here */
175 #define COPY(x) (err |= __put_user(x, retcode++))
176 
177  COPY(0x0000002AUL | (__NR_rt_sigreturn << 7));
178  /* MVK __NR_rt_sigreturn,B0 */
179  COPY(0x10000000UL); /* SWE */
180  COPY(0x00006000UL); /* NOP 4 */
181  COPY(0x00006000UL); /* NOP 4 */
182  COPY(0x00006000UL); /* NOP 4 */
183  COPY(0x00006000UL); /* NOP 4 */
184  COPY(0x00006000UL); /* NOP 4 */
185  COPY(0x00006000UL); /* NOP 4 */
186  COPY(0x00006000UL); /* NOP 4 */
187 
188 #undef COPY
189 
190  if (err)
191  goto segv_and_exit;
192 
193  flush_icache_range((unsigned long) &frame->retcode,
194  (unsigned long) &frame->retcode + RETCODE_SIZE);
195 
196  retcode = (unsigned long __user *) &frame->retcode;
197 
198  /* Change user context to branch to signal handler */
199  regs->sp = (unsigned long) frame - 8;
200  regs->b3 = (unsigned long) retcode;
201  regs->pc = (unsigned long) ka->sa.sa_handler;
202 
203  /* Give the signal number to the handler */
204  regs->a4 = signr;
205 
206  /*
207  * For realtime signals we must also set the second and third
208  * arguments for the signal handler.
209  * -- Peter Maydell <[email protected]> 2000-12-06
210  */
211  regs->b4 = (unsigned long)&frame->info;
212  regs->a6 = (unsigned long)&frame->uc;
213 
214  return 0;
215 
216 segv_and_exit:
217  force_sigsegv(signr, current);
218  return -EFAULT;
219 }
220 
221 static inline void
222 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
223 {
224  switch (regs->a4) {
225  case -ERESTARTNOHAND:
226  if (!has_handler)
227  goto do_restart;
228  regs->a4 = -EINTR;
229  break;
230 
231  case -ERESTARTSYS:
232  if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
233  regs->a4 = -EINTR;
234  break;
235  }
236  /* fallthrough */
237  case -ERESTARTNOINTR:
238 do_restart:
239  regs->a4 = regs->orig_a4;
240  regs->pc -= 4;
241  break;
242  }
243 }
244 
245 /*
246  * handle the actual delivery of a signal to userspace
247  */
248 static void handle_signal(int sig,
249  siginfo_t *info, struct k_sigaction *ka,
250  struct pt_regs *regs, int syscall)
251 {
252  /* Are we from a system call? */
253  if (syscall) {
254  /* If so, check system call restarting.. */
255  switch (regs->a4) {
256  case -ERESTART_RESTARTBLOCK:
257  case -ERESTARTNOHAND:
258  regs->a4 = -EINTR;
259  break;
260 
261  case -ERESTARTSYS:
262  if (!(ka->sa.sa_flags & SA_RESTART)) {
263  regs->a4 = -EINTR;
264  break;
265  }
266 
267  /* fallthrough */
268  case -ERESTARTNOINTR:
269  regs->a4 = regs->orig_a4;
270  regs->pc -= 4;
271  }
272  }
273 
274  /* Set up the stack frame */
275  if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
276  return;
277  signal_delivered(sig, info, ka, regs, 0);
278 }
279 
280 /*
281  * handle a potential signal
282  */
283 static void do_signal(struct pt_regs *regs, int syscall)
284 {
285  struct k_sigaction ka;
286  siginfo_t info;
287  int signr;
288 
289  /* we want the common case to go fast, which is why we may in certain
290  * cases get here from kernel mode */
291  if (!user_mode(regs))
292  return;
293 
294  signr = get_signal_to_deliver(&info, &ka, regs, NULL);
295  if (signr > 0) {
296  handle_signal(signr, &info, &ka, regs, syscall);
297  return;
298  }
299 
300  /* did we come from a system call? */
301  if (syscall) {
302  /* restart the system call - no handlers present */
303  switch (regs->a4) {
304  case -ERESTARTNOHAND:
305  case -ERESTARTSYS:
306  case -ERESTARTNOINTR:
307  regs->a4 = regs->orig_a4;
308  regs->pc -= 4;
309  break;
310 
311  case -ERESTART_RESTARTBLOCK:
312  regs->a4 = regs->orig_a4;
313  regs->b0 = __NR_restart_syscall;
314  regs->pc -= 4;
315  break;
316  }
317  }
318 
319  /* if there's no signal to deliver, we just put the saved sigmask
320  * back */
321  restore_saved_sigmask();
322 }
323 
324 /*
325  * notification of userspace execution resumption
326  * - triggered by current->work.notify_resume
327  */
328 asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags,
329  int syscall)
330 {
331  /* deal with pending signal delivery */
332  if (thread_info_flags & (1 << TIF_SIGPENDING))
333  do_signal(regs, syscall);
334 
335  if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) {
336  clear_thread_flag(TIF_NOTIFY_RESUME);
337  tracehook_notify_resume(regs);
338  }
339 }