diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-12-27 05:27:18 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-12-27 05:27:12 -0500 |
commit | aa33c8cbbae2eb98489a3a363099b362146a8f4c (patch) | |
tree | 315ac880b4a4af8f7c0c2822c2c5e5817033a5ab /arch/s390/kernel/signal.c | |
parent | 679e2ea73366cac81ede4104e6d3048cb806df2c (diff) |
[S390] cleanup trap handling
Move the program interruption code and the translation exception identifier
to the pt_regs structure as 'int_code' and 'int_parm_long' and make the
first level interrupt handler in entry[64].S store the two values. That
makes it possible to drop 'prot_addr' and 'trap_no' from the thread_struct
and to reduce the number of arguments to a lot of functions. Finally
un-inline do_trap. Overall this saves 5812 bytes in the .text section of
the 64 bit kernel.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/signal.c')
-rw-r--r-- | arch/s390/kernel/signal.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 7f6f9f354545..a8ba840294ff 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -302,9 +302,13 @@ static int setup_frame(int sig, struct k_sigaction *ka, | |||
302 | 302 | ||
303 | /* We forgot to include these in the sigcontext. | 303 | /* We forgot to include these in the sigcontext. |
304 | To avoid breaking binary compatibility, they are passed as args. */ | 304 | To avoid breaking binary compatibility, they are passed as args. */ |
305 | regs->gprs[4] = current->thread.trap_no; | 305 | if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || |
306 | regs->gprs[5] = current->thread.prot_addr; | 306 | sig == SIGTRAP || sig == SIGFPE) { |
307 | regs->gprs[6] = task_thread_info(current)->last_break; | 307 | /* set extra registers only for synchronous signals */ |
308 | regs->gprs[4] = regs->int_code & 127; | ||
309 | regs->gprs[5] = regs->int_parm_long; | ||
310 | regs->gprs[6] = task_thread_info(current)->last_break; | ||
311 | } | ||
308 | 312 | ||
309 | /* Place signal number on stack to allow backtrace from handler. */ | 313 | /* Place signal number on stack to allow backtrace from handler. */ |
310 | if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) | 314 | if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) |
@@ -434,13 +438,13 @@ void do_signal(struct pt_regs *regs) | |||
434 | * call information. | 438 | * call information. |
435 | */ | 439 | */ |
436 | current_thread_info()->system_call = | 440 | current_thread_info()->system_call = |
437 | test_thread_flag(TIF_SYSCALL) ? regs->svc_code : 0; | 441 | test_thread_flag(TIF_SYSCALL) ? regs->int_code : 0; |
438 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 442 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
439 | 443 | ||
440 | if (signr > 0) { | 444 | if (signr > 0) { |
441 | /* Whee! Actually deliver the signal. */ | 445 | /* Whee! Actually deliver the signal. */ |
442 | if (current_thread_info()->system_call) { | 446 | if (current_thread_info()->system_call) { |
443 | regs->svc_code = current_thread_info()->system_call; | 447 | regs->int_code = current_thread_info()->system_call; |
444 | /* Check for system call restarting. */ | 448 | /* Check for system call restarting. */ |
445 | switch (regs->gprs[2]) { | 449 | switch (regs->gprs[2]) { |
446 | case -ERESTART_RESTARTBLOCK: | 450 | case -ERESTART_RESTARTBLOCK: |
@@ -457,7 +461,7 @@ void do_signal(struct pt_regs *regs) | |||
457 | regs->gprs[2] = regs->orig_gpr2; | 461 | regs->gprs[2] = regs->orig_gpr2; |
458 | regs->psw.addr = | 462 | regs->psw.addr = |
459 | __rewind_psw(regs->psw, | 463 | __rewind_psw(regs->psw, |
460 | regs->svc_code >> 16); | 464 | regs->int_code >> 16); |
461 | break; | 465 | break; |
462 | } | 466 | } |
463 | } | 467 | } |
@@ -488,11 +492,11 @@ void do_signal(struct pt_regs *regs) | |||
488 | /* No handlers present - check for system call restart */ | 492 | /* No handlers present - check for system call restart */ |
489 | clear_thread_flag(TIF_SYSCALL); | 493 | clear_thread_flag(TIF_SYSCALL); |
490 | if (current_thread_info()->system_call) { | 494 | if (current_thread_info()->system_call) { |
491 | regs->svc_code = current_thread_info()->system_call; | 495 | regs->int_code = current_thread_info()->system_call; |
492 | switch (regs->gprs[2]) { | 496 | switch (regs->gprs[2]) { |
493 | case -ERESTART_RESTARTBLOCK: | 497 | case -ERESTART_RESTARTBLOCK: |
494 | /* Restart with sys_restart_syscall */ | 498 | /* Restart with sys_restart_syscall */ |
495 | regs->svc_code = __NR_restart_syscall; | 499 | regs->int_code = __NR_restart_syscall; |
496 | /* fallthrough */ | 500 | /* fallthrough */ |
497 | case -ERESTARTNOHAND: | 501 | case -ERESTARTNOHAND: |
498 | case -ERESTARTSYS: | 502 | case -ERESTARTSYS: |