diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-11-27 11:05:55 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-11-27 11:06:56 +0100 |
commit | 59da21398e680e8100625d689c8bebee6a139e93 (patch) | |
tree | 7d93f87d2942dac06367af8b3a269e9f6d557b29 /arch/s390/kernel/signal.c | |
parent | ed313489badef16d700f5a3be50e8fd8f8294bc8 (diff) | |
download | linux-59da21398e680e8100625d689c8bebee6a139e93.tar.bz2 |
[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.c | 6 |
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) current->thread.fp_regs.fpc &= FPC_VALID_MASK; restore_fp_regs(¤t->thread.fp_regs); - regs->trap = -1; /* disable syscall checks */ + regs->svcnr = 0; /* disable syscall checks */ return 0; } @@ -445,7 +445,7 @@ void do_signal(struct pt_regs *regs) oldset = ¤t->blocked; /* Are we from a system call? */ - if (regs->trap == __LC_SVC_OLD_PSW) { + if (regs->svcnr) { continue_addr = regs->psw.addr; restart_addr = continue_addr - regs->ilc; retval = regs->gprs[2]; @@ -462,7 +462,7 @@ void do_signal(struct pt_regs *regs) case -ERESTART_RESTARTBLOCK: regs->gprs[2] = -EINTR; } - regs->trap = -1; /* Don't deal with this again. */ + regs->svcnr = 0; /* Don't deal with this again. */ } /* Get signal to deliver. When running under ptrace, at this point |