aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/signal.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2008-11-27 05:05:55 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-11-27 05:06:56 -0500
commit59da21398e680e8100625d689c8bebee6a139e93 (patch)
tree7d93f87d2942dac06367af8b3a269e9f6d557b29 /arch/s390/kernel/signal.c
parented313489badef16d700f5a3be50e8fd8f8294bc8 (diff)
[S390] fix system call parameter functions.
syscall_get_nr() currently returns a valid result only if the call chain of the traced process includes do_syscall_trace_enter(). But collect_syscall() can be called for any sleeping task, the result of syscall_get_nr() in general is completely bogus. To make syscall_get_nr() work for any sleeping task the traps field in pt_regs is replace with svcnr - the system call number the process is executing. If svcnr == 0 the process is not on a system call path. The syscall_get_arguments and syscall_set_arguments use regs->gprs[2] for the first system call parameter. This is incorrect since gprs[2] may have been overwritten with the system call number if the call chain includes do_syscall_trace_enter. Use regs->orig_gprs2 instead. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/signal.c')
-rw-r--r--arch/s390/kernel/signal.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 4f7fc3059a8e..8e6812a22670 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -160,7 +160,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
160 current->thread.fp_regs.fpc &= FPC_VALID_MASK; 160 current->thread.fp_regs.fpc &= FPC_VALID_MASK;
161 161
162 restore_fp_regs(&current->thread.fp_regs); 162 restore_fp_regs(&current->thread.fp_regs);
163 regs->trap = -1; /* disable syscall checks */ 163 regs->svcnr = 0; /* disable syscall checks */
164 return 0; 164 return 0;
165} 165}
166 166
@@ -445,7 +445,7 @@ void do_signal(struct pt_regs *regs)
445 oldset = &current->blocked; 445 oldset = &current->blocked;
446 446
447 /* Are we from a system call? */ 447 /* Are we from a system call? */
448 if (regs->trap == __LC_SVC_OLD_PSW) { 448 if (regs->svcnr) {
449 continue_addr = regs->psw.addr; 449 continue_addr = regs->psw.addr;
450 restart_addr = continue_addr - regs->ilc; 450 restart_addr = continue_addr - regs->ilc;
451 retval = regs->gprs[2]; 451 retval = regs->gprs[2];
@@ -462,7 +462,7 @@ void do_signal(struct pt_regs *regs)
462 case -ERESTART_RESTARTBLOCK: 462 case -ERESTART_RESTARTBLOCK:
463 regs->gprs[2] = -EINTR; 463 regs->gprs[2] = -EINTR;
464 } 464 }
465 regs->trap = -1; /* Don't deal with this again. */ 465 regs->svcnr = 0; /* Don't deal with this again. */
466 } 466 }
467 467
468 /* Get signal to deliver. When running under ptrace, at this point 468 /* Get signal to deliver. When running under ptrace, at this point