aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mn10300/kernel/signal.c')
-rw-r--r--arch/mn10300/kernel/signal.c89
1 files changed, 36 insertions, 53 deletions
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 9dfac5cd16e6..0c97202764ce 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -207,16 +207,16 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
207/* 207/*
208 * set up a normal signal frame 208 * set up a normal signal frame
209 */ 209 */
210static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 210static int setup_frame(struct ksignal *ksig, sigset_t *set,
211 struct pt_regs *regs) 211 struct pt_regs *regs)
212{ 212{
213 struct sigframe __user *frame; 213 struct sigframe __user *frame;
214 int rsig; 214 int rsig, sig = ksig->sig;
215 215
216 frame = get_sigframe(ka, regs, sizeof(*frame)); 216 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
217 217
218 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 218 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
219 goto give_sigsegv; 219 return -EFAULT;
220 220
221 rsig = sig; 221 rsig = sig;
222 if (sig < 32 && 222 if (sig < 32 &&
@@ -226,40 +226,40 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
226 226
227 if (__put_user(rsig, &frame->sig) < 0 || 227 if (__put_user(rsig, &frame->sig) < 0 ||
228 __put_user(&frame->sc, &frame->psc) < 0) 228 __put_user(&frame->sc, &frame->psc) < 0)
229 goto give_sigsegv; 229 return -EFAULT;
230 230
231 if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0])) 231 if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0]))
232 goto give_sigsegv; 232 return -EFAULT;
233 233
234 if (_NSIG_WORDS > 1) { 234 if (_NSIG_WORDS > 1) {
235 if (__copy_to_user(frame->extramask, &set->sig[1], 235 if (__copy_to_user(frame->extramask, &set->sig[1],
236 sizeof(frame->extramask))) 236 sizeof(frame->extramask)))
237 goto give_sigsegv; 237 return -EFAULT;
238 } 238 }
239 239
240 /* set up to return from userspace. If provided, use a stub already in 240 /* set up to return from userspace. If provided, use a stub already in
241 * userspace */ 241 * userspace */
242 if (ka->sa.sa_flags & SA_RESTORER) { 242 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
243 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 243 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
244 goto give_sigsegv; 244 return -EFAULT;
245 } else { 245 } else {
246 if (__put_user((void (*)(void))frame->retcode, 246 if (__put_user((void (*)(void))frame->retcode,
247 &frame->pretcode)) 247 &frame->pretcode))
248 goto give_sigsegv; 248 return -EFAULT;
249 /* this is mov $,d0; syscall 0 */ 249 /* this is mov $,d0; syscall 0 */
250 if (__put_user(0x2c, (char *)(frame->retcode + 0)) || 250 if (__put_user(0x2c, (char *)(frame->retcode + 0)) ||
251 __put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) || 251 __put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) ||
252 __put_user(0x00, (char *)(frame->retcode + 2)) || 252 __put_user(0x00, (char *)(frame->retcode + 2)) ||
253 __put_user(0xf0, (char *)(frame->retcode + 3)) || 253 __put_user(0xf0, (char *)(frame->retcode + 3)) ||
254 __put_user(0xe0, (char *)(frame->retcode + 4))) 254 __put_user(0xe0, (char *)(frame->retcode + 4)))
255 goto give_sigsegv; 255 return -EFAULT;
256 flush_icache_range((unsigned long) frame->retcode, 256 flush_icache_range((unsigned long) frame->retcode,
257 (unsigned long) frame->retcode + 5); 257 (unsigned long) frame->retcode + 5);
258 } 258 }
259 259
260 /* set up registers for signal handler */ 260 /* set up registers for signal handler */
261 regs->sp = (unsigned long) frame; 261 regs->sp = (unsigned long) frame;
262 regs->pc = (unsigned long) ka->sa.sa_handler; 262 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
263 regs->d0 = sig; 263 regs->d0 = sig;
264 regs->d1 = (unsigned long) &frame->sc; 264 regs->d1 = (unsigned long) &frame->sc;
265 265
@@ -270,25 +270,21 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
270#endif 270#endif
271 271
272 return 0; 272 return 0;
273
274give_sigsegv:
275 force_sigsegv(sig, current);
276 return -EFAULT;
277} 273}
278 274
279/* 275/*
280 * set up a realtime signal frame 276 * set up a realtime signal frame
281 */ 277 */
282static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 278static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
283 sigset_t *set, struct pt_regs *regs) 279 struct pt_regs *regs)
284{ 280{
285 struct rt_sigframe __user *frame; 281 struct rt_sigframe __user *frame;
286 int rsig; 282 int rsig, sig = ksig->sig;
287 283
288 frame = get_sigframe(ka, regs, sizeof(*frame)); 284 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
289 285
290 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 286 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
291 goto give_sigsegv; 287 return -EFAULT;
292 288
293 rsig = sig; 289 rsig = sig;
294 if (sig < 32 && 290 if (sig < 32 &&
@@ -299,8 +295,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
299 if (__put_user(rsig, &frame->sig) || 295 if (__put_user(rsig, &frame->sig) ||
300 __put_user(&frame->info, &frame->pinfo) || 296 __put_user(&frame->info, &frame->pinfo) ||
301 __put_user(&frame->uc, &frame->puc) || 297 __put_user(&frame->uc, &frame->puc) ||
302 copy_siginfo_to_user(&frame->info, info)) 298 copy_siginfo_to_user(&frame->info, &ksig->info))
303 goto give_sigsegv; 299 return -EFAULT;
304 300
305 /* create the ucontext. */ 301 /* create the ucontext. */
306 if (__put_user(0, &frame->uc.uc_flags) || 302 if (__put_user(0, &frame->uc.uc_flags) ||
@@ -309,13 +305,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
309 setup_sigcontext(&frame->uc.uc_mcontext, 305 setup_sigcontext(&frame->uc.uc_mcontext,
310 &frame->fpuctx, regs, set->sig[0]) || 306 &frame->fpuctx, regs, set->sig[0]) ||
311 __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) 307 __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
312 goto give_sigsegv; 308 return -EFAULT;
313 309
314 /* set up to return from userspace. If provided, use a stub already in 310 /* set up to return from userspace. If provided, use a stub already in
315 * userspace */ 311 * userspace */
316 if (ka->sa.sa_flags & SA_RESTORER) { 312 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
317 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 313 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
318 goto give_sigsegv; 314 return -EFAULT;
315
319 } else { 316 } else {
320 if (__put_user((void(*)(void))frame->retcode, 317 if (__put_user((void(*)(void))frame->retcode,
321 &frame->pretcode) || 318 &frame->pretcode) ||
@@ -326,7 +323,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
326 __put_user(0x00, (char *)(frame->retcode + 2)) || 323 __put_user(0x00, (char *)(frame->retcode + 2)) ||
327 __put_user(0xf0, (char *)(frame->retcode + 3)) || 324 __put_user(0xf0, (char *)(frame->retcode + 3)) ||
328 __put_user(0xe0, (char *)(frame->retcode + 4))) 325 __put_user(0xe0, (char *)(frame->retcode + 4)))
329 goto give_sigsegv; 326 return -EFAULT;
330 327
331 flush_icache_range((u_long) frame->retcode, 328 flush_icache_range((u_long) frame->retcode,
332 (u_long) frame->retcode + 5); 329 (u_long) frame->retcode + 5);
@@ -334,7 +331,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
334 331
335 /* Set up registers for signal handler */ 332 /* Set up registers for signal handler */
336 regs->sp = (unsigned long) frame; 333 regs->sp = (unsigned long) frame;
337 regs->pc = (unsigned long) ka->sa.sa_handler; 334 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
338 regs->d0 = sig; 335 regs->d0 = sig;
339 regs->d1 = (long) &frame->info; 336 regs->d1 = (long) &frame->info;
340 337
@@ -345,10 +342,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
345#endif 342#endif
346 343
347 return 0; 344 return 0;
348
349give_sigsegv:
350 force_sigsegv(sig, current);
351 return -EFAULT;
352} 345}
353 346
354static inline void stepback(struct pt_regs *regs) 347static inline void stepback(struct pt_regs *regs)
@@ -360,9 +353,7 @@ static inline void stepback(struct pt_regs *regs)
360/* 353/*
361 * handle the actual delivery of a signal to userspace 354 * handle the actual delivery of a signal to userspace
362 */ 355 */
363static int handle_signal(int sig, 356static int handle_signal(struct ksignal *ksig, struct pt_regs *regs)
364 siginfo_t *info, struct k_sigaction *ka,
365 struct pt_regs *regs)
366{ 357{
367 sigset_t *oldset = sigmask_to_save(); 358 sigset_t *oldset = sigmask_to_save();
368 int ret; 359 int ret;
@@ -377,7 +368,7 @@ static int handle_signal(int sig,
377 break; 368 break;
378 369
379 case -ERESTARTSYS: 370 case -ERESTARTSYS:
380 if (!(ka->sa.sa_flags & SA_RESTART)) { 371 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
381 regs->d0 = -EINTR; 372 regs->d0 = -EINTR;
382 break; 373 break;
383 } 374 }
@@ -390,15 +381,12 @@ static int handle_signal(int sig,
390 } 381 }
391 382
392 /* Set up the stack frame */ 383 /* Set up the stack frame */
393 if (ka->sa.sa_flags & SA_SIGINFO) 384 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
394 ret = setup_rt_frame(sig, ka, info, oldset, regs); 385 ret = setup_rt_frame(ksig, oldset, regs);
395 else 386 else
396 ret = setup_frame(sig, ka, oldset, regs); 387 ret = setup_frame(ksig, oldset, regs);
397 if (ret)
398 return ret;
399 388
400 signal_delivered(sig, info, ka, regs, 389 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
401 test_thread_flag(TIF_SINGLESTEP));
402 return 0; 390 return 0;
403} 391}
404 392
@@ -407,15 +395,10 @@ static int handle_signal(int sig,
407 */ 395 */
408static void do_signal(struct pt_regs *regs) 396static void do_signal(struct pt_regs *regs)
409{ 397{
410 struct k_sigaction ka; 398 struct ksignal ksig;
411 siginfo_t info;
412 int signr;
413
414 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
415 if (signr > 0) {
416 if (handle_signal(signr, &info, &ka, regs) == 0) {
417 }
418 399
400 if (get_signal(&ksig)) {
401 handle_signal(&ksig, regs);
419 return; 402 return;
420 } 403 }
421 404