diff options
Diffstat (limited to 'arch/cris/arch-v32/kernel/signal.c')
-rw-r--r-- | arch/cris/arch-v32/kernel/signal.c | 77 |
1 files changed, 30 insertions, 47 deletions
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index 01d1375c9004..cc7a39a74aec 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c | |||
@@ -215,23 +215,22 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
215 | * trampoline. | 215 | * trampoline. |
216 | */ | 216 | */ |
217 | static int | 217 | static int |
218 | setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | 218 | setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) |
219 | struct pt_regs * regs) | ||
220 | { | 219 | { |
221 | int err; | 220 | int err; |
222 | unsigned long return_ip; | 221 | unsigned long return_ip; |
223 | struct signal_frame __user *frame; | 222 | struct signal_frame __user *frame; |
224 | 223 | ||
225 | err = 0; | 224 | err = 0; |
226 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 225 | frame = get_sigframe(&ksig->ka, regs, sizeof(*frame)); |
227 | 226 | ||
228 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 227 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
229 | goto give_sigsegv; | 228 | return -EFAULT; |
230 | 229 | ||
231 | err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); | 230 | err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); |
232 | 231 | ||
233 | if (err) | 232 | if (err) |
234 | goto give_sigsegv; | 233 | return -EFAULT; |
235 | 234 | ||
236 | if (_NSIG_WORDS > 1) { | 235 | if (_NSIG_WORDS > 1) { |
237 | err |= __copy_to_user(frame->extramask, &set->sig[1], | 236 | err |= __copy_to_user(frame->extramask, &set->sig[1], |
@@ -239,14 +238,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
239 | } | 238 | } |
240 | 239 | ||
241 | if (err) | 240 | if (err) |
242 | goto give_sigsegv; | 241 | return -EFAULT; |
243 | 242 | ||
244 | /* | 243 | /* |
245 | * Set up to return from user-space. If provided, use a stub | 244 | * Set up to return from user-space. If provided, use a stub |
246 | * already located in user-space. | 245 | * already located in user-space. |
247 | */ | 246 | */ |
248 | if (ka->sa.sa_flags & SA_RESTORER) { | 247 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
249 | return_ip = (unsigned long)ka->sa.sa_restorer; | 248 | return_ip = (unsigned long)ksig->ka.sa.sa_restorer; |
250 | } else { | 249 | } else { |
251 | /* Trampoline - the desired return ip is in the signal return page. */ | 250 | /* Trampoline - the desired return ip is in the signal return page. */ |
252 | return_ip = cris_signal_return_page; | 251 | return_ip = cris_signal_return_page; |
@@ -264,7 +263,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
264 | } | 263 | } |
265 | 264 | ||
266 | if (err) | 265 | if (err) |
267 | goto give_sigsegv; | 266 | return -EFAULT; |
268 | 267 | ||
269 | /* | 268 | /* |
270 | * Set up registers for signal handler. | 269 | * Set up registers for signal handler. |
@@ -273,42 +272,37 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
273 | * Where the code enter later. | 272 | * Where the code enter later. |
274 | * First argument, signo. | 273 | * First argument, signo. |
275 | */ | 274 | */ |
276 | regs->erp = (unsigned long) ka->sa.sa_handler; | 275 | regs->erp = (unsigned long) ksig->ka.sa.sa_handler; |
277 | regs->srp = return_ip; | 276 | regs->srp = return_ip; |
278 | regs->r10 = sig; | 277 | regs->r10 = ksig->sig; |
279 | 278 | ||
280 | /* Actually move the USP to reflect the stacked frame. */ | 279 | /* Actually move the USP to reflect the stacked frame. */ |
281 | wrusp((unsigned long)frame); | 280 | wrusp((unsigned long)frame); |
282 | 281 | ||
283 | return 0; | 282 | return 0; |
284 | |||
285 | give_sigsegv: | ||
286 | force_sigsegv(sig, current); | ||
287 | return -EFAULT; | ||
288 | } | 283 | } |
289 | 284 | ||
290 | static int | 285 | static int |
291 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 286 | setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) |
292 | sigset_t *set, struct pt_regs * regs) | ||
293 | { | 287 | { |
294 | int err; | 288 | int err; |
295 | unsigned long return_ip; | 289 | unsigned long return_ip; |
296 | struct rt_signal_frame __user *frame; | 290 | struct rt_signal_frame __user *frame; |
297 | 291 | ||
298 | err = 0; | 292 | err = 0; |
299 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 293 | frame = get_sigframe(&ksig->ka, regs, sizeof(*frame)); |
300 | 294 | ||
301 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 295 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
302 | goto give_sigsegv; | 296 | return -EFAULT; |
303 | 297 | ||
304 | /* TODO: what is the current->exec_domain stuff and invmap ? */ | 298 | /* TODO: what is the current->exec_domain stuff and invmap ? */ |
305 | 299 | ||
306 | err |= __put_user(&frame->info, &frame->pinfo); | 300 | err |= __put_user(&frame->info, &frame->pinfo); |
307 | err |= __put_user(&frame->uc, &frame->puc); | 301 | err |= __put_user(&frame->uc, &frame->puc); |
308 | err |= copy_siginfo_to_user(&frame->info, info); | 302 | err |= copy_siginfo_to_user(&frame->info, &ksig->info); |
309 | 303 | ||
310 | if (err) | 304 | if (err) |
311 | goto give_sigsegv; | 305 | return -EFAULT; |
312 | 306 | ||
313 | /* Clear all the bits of the ucontext we don't use. */ | 307 | /* Clear all the bits of the ucontext we don't use. */ |
314 | err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); | 308 | err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); |
@@ -317,14 +311,14 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
317 | err |= __save_altstack(&frame->uc.uc_stack, rdusp()); | 311 | err |= __save_altstack(&frame->uc.uc_stack, rdusp()); |
318 | 312 | ||
319 | if (err) | 313 | if (err) |
320 | goto give_sigsegv; | 314 | return -EFAULT; |
321 | 315 | ||
322 | /* | 316 | /* |
323 | * Set up to return from user-space. If provided, use a stub | 317 | * Set up to return from user-space. If provided, use a stub |
324 | * already located in user-space. | 318 | * already located in user-space. |
325 | */ | 319 | */ |
326 | if (ka->sa.sa_flags & SA_RESTORER) { | 320 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
327 | return_ip = (unsigned long) ka->sa.sa_restorer; | 321 | return_ip = (unsigned long) ksig->ka.sa.sa_restorer; |
328 | } else { | 322 | } else { |
329 | /* Trampoline - the desired return ip is in the signal return page. */ | 323 | /* Trampoline - the desired return ip is in the signal return page. */ |
330 | return_ip = cris_signal_return_page + 6; | 324 | return_ip = cris_signal_return_page + 6; |
@@ -345,7 +339,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
345 | } | 339 | } |
346 | 340 | ||
347 | if (err) | 341 | if (err) |
348 | goto give_sigsegv; | 342 | return -EFAULT; |
349 | 343 | ||
350 | /* | 344 | /* |
351 | * Set up registers for signal handler. | 345 | * Set up registers for signal handler. |
@@ -356,9 +350,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
356 | * Second argument is (siginfo_t *). | 350 | * Second argument is (siginfo_t *). |
357 | * Third argument is unused. | 351 | * Third argument is unused. |
358 | */ | 352 | */ |
359 | regs->erp = (unsigned long) ka->sa.sa_handler; | 353 | regs->erp = (unsigned long) ksig->ka.sa.sa_handler; |
360 | regs->srp = return_ip; | 354 | regs->srp = return_ip; |
361 | regs->r10 = sig; | 355 | regs->r10 = ksig->sig; |
362 | regs->r11 = (unsigned long) &frame->info; | 356 | regs->r11 = (unsigned long) &frame->info; |
363 | regs->r12 = 0; | 357 | regs->r12 = 0; |
364 | 358 | ||
@@ -366,17 +360,11 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
366 | wrusp((unsigned long)frame); | 360 | wrusp((unsigned long)frame); |
367 | 361 | ||
368 | return 0; | 362 | return 0; |
369 | |||
370 | give_sigsegv: | ||
371 | force_sigsegv(sig, current); | ||
372 | return -EFAULT; | ||
373 | } | 363 | } |
374 | 364 | ||
375 | /* Invoke a signal handler to, well, handle the signal. */ | 365 | /* Invoke a signal handler to, well, handle the signal. */ |
376 | static inline void | 366 | static inline void |
377 | handle_signal(int canrestart, unsigned long sig, | 367 | handle_signal(int canrestart, struct ksignal *ksig, struct pt_regs *regs) |
378 | siginfo_t *info, struct k_sigaction *ka, | ||
379 | struct pt_regs * regs) | ||
380 | { | 368 | { |
381 | sigset_t *oldset = sigmask_to_save(); | 369 | sigset_t *oldset = sigmask_to_save(); |
382 | int ret; | 370 | int ret; |
@@ -404,7 +392,7 @@ handle_signal(int canrestart, unsigned long sig, | |||
404 | * there is no handler, or the handler | 392 | * there is no handler, or the handler |
405 | * was registered with SA_RESTART. | 393 | * was registered with SA_RESTART. |
406 | */ | 394 | */ |
407 | if (!(ka->sa.sa_flags & SA_RESTART)) { | 395 | if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { |
408 | regs->r10 = -EINTR; | 396 | regs->r10 = -EINTR; |
409 | break; | 397 | break; |
410 | } | 398 | } |
@@ -423,13 +411,12 @@ handle_signal(int canrestart, unsigned long sig, | |||
423 | } | 411 | } |
424 | 412 | ||
425 | /* Set up the stack frame. */ | 413 | /* Set up the stack frame. */ |
426 | if (ka->sa.sa_flags & SA_SIGINFO) | 414 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
427 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 415 | ret = setup_rt_frame(ksig, oldset, regs); |
428 | else | 416 | else |
429 | ret = setup_frame(sig, ka, oldset, regs); | 417 | ret = setup_frame(ksig, oldset, regs); |
430 | 418 | ||
431 | if (ret == 0) | 419 | signal_setup_done(ret, ksig, 0); |
432 | signal_delivered(sig, info, ka, regs, 0); | ||
433 | } | 420 | } |
434 | 421 | ||
435 | /* | 422 | /* |
@@ -446,9 +433,7 @@ handle_signal(int canrestart, unsigned long sig, | |||
446 | void | 433 | void |
447 | do_signal(int canrestart, struct pt_regs *regs) | 434 | do_signal(int canrestart, struct pt_regs *regs) |
448 | { | 435 | { |
449 | int signr; | 436 | struct ksignal ksig; |
450 | siginfo_t info; | ||
451 | struct k_sigaction ka; | ||
452 | 437 | ||
453 | /* | 438 | /* |
454 | * The common case should go fast, which is why this point is | 439 | * The common case should go fast, which is why this point is |
@@ -458,11 +443,9 @@ do_signal(int canrestart, struct pt_regs *regs) | |||
458 | if (!user_mode(regs)) | 443 | if (!user_mode(regs)) |
459 | return; | 444 | return; |
460 | 445 | ||
461 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 446 | if (get_signal(&ksig)) { |
462 | |||
463 | if (signr > 0) { | ||
464 | /* Whee! Actually deliver the signal. */ | 447 | /* Whee! Actually deliver the signal. */ |
465 | handle_signal(canrestart, signr, &info, &ka, regs); | 448 | handle_signal(canrestart, &ksig, regs); |
466 | return; | 449 | return; |
467 | } | 450 | } |
468 | 451 | ||