aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2013-10-07 06:56:24 -0400
committerRichard Weinberger <richard@sigma-star.at>2014-08-06 07:02:13 -0400
commitfa0197722eb7559a6a9733881bbb8d9e76364f33 (patch)
treebd7f998a6f8038a93215a2522669abc7d65577ff /arch/cris
parente19c025bc9a184ed9c5daf06ffb89abc81d1696a (diff)
cris: Use get_signal() signal_setup_done()
Use the more generic functions get_signal() signal_setup_done() for signal delivery. Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/cris')
-rw-r--r--arch/cris/arch-v10/kernel/signal.c79
-rw-r--r--arch/cris/arch-v32/kernel/signal.c77
2 files changed, 63 insertions, 93 deletions
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 61ce6273a895..12aac1fb48df 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -228,33 +228,33 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
228 * user-mode trampoline. 228 * user-mode trampoline.
229 */ 229 */
230 230
231static int setup_frame(int sig, struct k_sigaction *ka, 231static int setup_frame(struct ksignal *ksig, sigset_t *set,
232 sigset_t *set, struct pt_regs *regs) 232 struct pt_regs *regs)
233{ 233{
234 struct sigframe __user *frame; 234 struct sigframe __user *frame;
235 unsigned long return_ip; 235 unsigned long return_ip;
236 int err = 0; 236 int err = 0;
237 237
238 frame = get_sigframe(ka, regs, sizeof(*frame)); 238 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
239 239
240 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 240 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
241 goto give_sigsegv; 241 return -EFAULT;
242 242
243 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); 243 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
244 if (err) 244 if (err)
245 goto give_sigsegv; 245 return -EFAULT;
246 246
247 if (_NSIG_WORDS > 1) { 247 if (_NSIG_WORDS > 1) {
248 err |= __copy_to_user(frame->extramask, &set->sig[1], 248 err |= __copy_to_user(frame->extramask, &set->sig[1],
249 sizeof(frame->extramask)); 249 sizeof(frame->extramask));
250 } 250 }
251 if (err) 251 if (err)
252 goto give_sigsegv; 252 return -EFAULT;
253 253
254 /* Set up to return from userspace. If provided, use a stub 254 /* Set up to return from userspace. If provided, use a stub
255 already in userspace. */ 255 already in userspace. */
256 if (ka->sa.sa_flags & SA_RESTORER) { 256 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
257 return_ip = (unsigned long)ka->sa.sa_restorer; 257 return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
258 } else { 258 } else {
259 /* trampoline - the desired return ip is the retcode itself */ 259 /* trampoline - the desired return ip is the retcode itself */
260 return_ip = (unsigned long)&frame->retcode; 260 return_ip = (unsigned long)&frame->retcode;
@@ -265,42 +265,38 @@ static int setup_frame(int sig, struct k_sigaction *ka,
265 } 265 }
266 266
267 if (err) 267 if (err)
268 goto give_sigsegv; 268 return -EFAULT;
269 269
270 /* Set up registers for signal handler */ 270 /* Set up registers for signal handler */
271 271
272 regs->irp = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ 272 regs->irp = (unsigned long) ksig->ka.sa.sa_handler; /* what we enter NOW */
273 regs->srp = return_ip; /* what we enter LATER */ 273 regs->srp = return_ip; /* what we enter LATER */
274 regs->r10 = sig; /* first argument is signo */ 274 regs->r10 = ksig->sig; /* first argument is signo */
275 275
276 /* actually move the usp to reflect the stacked frame */ 276 /* actually move the usp to reflect the stacked frame */
277 277
278 wrusp((unsigned long)frame); 278 wrusp((unsigned long)frame);
279 279
280 return 0; 280 return 0;
281
282give_sigsegv:
283 force_sigsegv(sig, current);
284 return -EFAULT;
285} 281}
286 282
287static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 283static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
288 sigset_t *set, struct pt_regs *regs) 284 struct pt_regs *regs)
289{ 285{
290 struct rt_sigframe __user *frame; 286 struct rt_sigframe __user *frame;
291 unsigned long return_ip; 287 unsigned long return_ip;
292 int err = 0; 288 int err = 0;
293 289
294 frame = get_sigframe(ka, regs, sizeof(*frame)); 290 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
295 291
296 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 292 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
297 goto give_sigsegv; 293 return -EFAULT;
298 294
299 err |= __put_user(&frame->info, &frame->pinfo); 295 err |= __put_user(&frame->info, &frame->pinfo);
300 err |= __put_user(&frame->uc, &frame->puc); 296 err |= __put_user(&frame->uc, &frame->puc);
301 err |= copy_siginfo_to_user(&frame->info, info); 297 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
302 if (err) 298 if (err)
303 goto give_sigsegv; 299 return -EFAULT;
304 300
305 /* Clear all the bits of the ucontext we don't use. */ 301 /* Clear all the bits of the ucontext we don't use. */
306 err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); 302 err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
@@ -312,12 +308,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
312 err |= __save_altstack(&frame->uc.uc_stack, rdusp()); 308 err |= __save_altstack(&frame->uc.uc_stack, rdusp());
313 309
314 if (err) 310 if (err)
315 goto give_sigsegv; 311 return -EFAULT;
316 312
317 /* Set up to return from userspace. If provided, use a stub 313 /* Set up to return from userspace. If provided, use a stub
318 already in userspace. */ 314 already in userspace. */
319 if (ka->sa.sa_flags & SA_RESTORER) { 315 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
320 return_ip = (unsigned long)ka->sa.sa_restorer; 316 return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
321 } else { 317 } else {
322 /* trampoline - the desired return ip is the retcode itself */ 318 /* trampoline - the desired return ip is the retcode itself */
323 return_ip = (unsigned long)&frame->retcode; 319 return_ip = (unsigned long)&frame->retcode;
@@ -329,18 +325,18 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
329 } 325 }
330 326
331 if (err) 327 if (err)
332 goto give_sigsegv; 328 return -EFAULT;
333 329
334 /* TODO what is the current->exec_domain stuff and invmap ? */ 330 /* TODO what is the current->exec_domain stuff and invmap ? */
335 331
336 /* Set up registers for signal handler */ 332 /* Set up registers for signal handler */
337 333
338 /* What we enter NOW */ 334 /* What we enter NOW */
339 regs->irp = (unsigned long) ka->sa.sa_handler; 335 regs->irp = (unsigned long) ksig->ka.sa.sa_handler;
340 /* What we enter LATER */ 336 /* What we enter LATER */
341 regs->srp = return_ip; 337 regs->srp = return_ip;
342 /* First argument is signo */ 338 /* First argument is signo */
343 regs->r10 = sig; 339 regs->r10 = ksig->sig;
344 /* Second argument is (siginfo_t *) */ 340 /* Second argument is (siginfo_t *) */
345 regs->r11 = (unsigned long)&frame->info; 341 regs->r11 = (unsigned long)&frame->info;
346 /* Third argument is unused */ 342 /* Third argument is unused */
@@ -350,19 +346,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
350 wrusp((unsigned long)frame); 346 wrusp((unsigned long)frame);
351 347
352 return 0; 348 return 0;
353
354give_sigsegv:
355 force_sigsegv(sig, current);
356 return -EFAULT;
357} 349}
358 350
359/* 351/*
360 * OK, we're invoking a handler 352 * OK, we're invoking a handler
361 */ 353 */
362 354
363static inline void handle_signal(int canrestart, unsigned long sig, 355static inline void handle_signal(int canrestart, struct ksignal *ksig,
364 siginfo_t *info, struct k_sigaction *ka, 356 struct pt_regs *regs)
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;
@@ -383,7 +374,7 @@ static inline void handle_signal(int canrestart, unsigned long sig,
383 /* ERESTARTSYS means to restart the syscall if 374 /* ERESTARTSYS means to restart the syscall if
384 * there is no handler or the handler was 375 * there is no handler or the handler was
385 * registered with SA_RESTART */ 376 * registered with SA_RESTART */
386 if (!(ka->sa.sa_flags & SA_RESTART)) { 377 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
387 regs->r10 = -EINTR; 378 regs->r10 = -EINTR;
388 break; 379 break;
389 } 380 }
@@ -396,13 +387,12 @@ static inline void handle_signal(int canrestart, unsigned long sig,
396 } 387 }
397 388
398 /* Set up the stack frame */ 389 /* Set up the stack frame */
399 if (ka->sa.sa_flags & SA_SIGINFO) 390 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
400 ret = setup_rt_frame(sig, ka, info, oldset, regs); 391 ret = setup_rt_frame(ksig, oldset, regs);
401 else 392 else
402 ret = setup_frame(sig, ka, oldset, regs); 393 ret = setup_frame(ksig, oldset, regs);
403 394
404 if (ret == 0) 395 signal_setup_done(ret, ksig, 0);
405 signal_delivered(sig, info, ka, regs, 0);
406} 396}
407 397
408/* 398/*
@@ -419,9 +409,7 @@ static inline void handle_signal(int canrestart, unsigned long sig,
419 409
420void do_signal(int canrestart, struct pt_regs *regs) 410void do_signal(int canrestart, struct pt_regs *regs)
421{ 411{
422 siginfo_t info; 412 struct ksignal ksig;
423 int signr;
424 struct k_sigaction ka;
425 413
426 /* 414 /*
427 * We want the common case to go fast, which 415 * We want the common case to go fast, which
@@ -432,10 +420,9 @@ void do_signal(int canrestart, struct pt_regs *regs)
432 if (!user_mode(regs)) 420 if (!user_mode(regs))
433 return; 421 return;
434 422
435 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 423 if (get_signal(&ksig)) {
436 if (signr > 0) {
437 /* Whee! Actually deliver the signal. */ 424 /* Whee! Actually deliver the signal. */
438 handle_signal(canrestart, signr, &info, &ka, regs); 425 handle_signal(canrestart, &ksig, regs);
439 return; 426 return;
440 } 427 }
441 428
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