aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v32/kernel/signal.c')
-rw-r--r--arch/cris/arch-v32/kernel/signal.c77
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 */
217static int 217static int
218setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 218setup_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
285give_sigsegv:
286 force_sigsegv(sig, current);
287 return -EFAULT;
288} 283}
289 284
290static int 285static int
291setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 286setup_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
370give_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. */
376static inline void 366static inline void
377handle_signal(int canrestart, unsigned long sig, 367handle_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,
446void 433void
447do_signal(int canrestart, struct pt_regs *regs) 434do_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