diff options
author | Roland McGrath <roland@redhat.com> | 2008-07-27 03:30:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-27 20:28:55 -0400 |
commit | 73ccefab8a6590bb3d5b44c046010139108ab7ca (patch) | |
tree | 76b9ebc1fb2bc80b4d01d95a232220ac0012972b /arch/sparc64 | |
parent | 5cfc17766685c79d1a348bce24af9c9dbc0d8d67 (diff) |
sparc64: tracehook syscall
This changes sparc64 syscall tracing to use the new tracehook.h entry
points.
[ Add assembly changes to force an immediate -ENOSYS return from
the system call when syscall_trace() returns non-zero at syscall
entry. -DaveM ]
Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/kernel/entry.h | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/ptrace.c | 32 | ||||
-rw-r--r-- | arch/sparc64/kernel/syscalls.S | 4 |
3 files changed, 17 insertions, 22 deletions
diff --git a/arch/sparc64/kernel/entry.h b/arch/sparc64/kernel/entry.h index 32fbab620852..fc294a292899 100644 --- a/arch/sparc64/kernel/entry.h +++ b/arch/sparc64/kernel/entry.h | |||
@@ -22,8 +22,7 @@ extern void do_notify_resume(struct pt_regs *regs, | |||
22 | unsigned long orig_i0, | 22 | unsigned long orig_i0, |
23 | unsigned long thread_info_flags); | 23 | unsigned long thread_info_flags); |
24 | 24 | ||
25 | extern asmlinkage void syscall_trace(struct pt_regs *regs, | 25 | extern asmlinkage int syscall_trace(struct pt_regs *regs, int syscall_exit_p); |
26 | int syscall_exit_p); | ||
27 | 26 | ||
28 | extern void bad_trap_tl1(struct pt_regs *regs, long lvl); | 27 | extern void bad_trap_tl1(struct pt_regs *regs, long lvl); |
29 | 28 | ||
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index f6c9fc92921d..bd578cc4856d 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/audit.h> | 23 | #include <linux/audit.h> |
24 | #include <linux/signal.h> | 24 | #include <linux/signal.h> |
25 | #include <linux/regset.h> | 25 | #include <linux/regset.h> |
26 | #include <linux/tracehook.h> | ||
26 | #include <linux/compat.h> | 27 | #include <linux/compat.h> |
27 | #include <linux/elf.h> | 28 | #include <linux/elf.h> |
28 | 29 | ||
@@ -1049,8 +1050,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1049 | return ret; | 1050 | return ret; |
1050 | } | 1051 | } |
1051 | 1052 | ||
1052 | asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p) | 1053 | asmlinkage int syscall_trace(struct pt_regs *regs, int syscall_exit_p) |
1053 | { | 1054 | { |
1055 | int ret = 0; | ||
1056 | |||
1054 | /* do the secure computing check first */ | 1057 | /* do the secure computing check first */ |
1055 | secure_computing(regs->u_regs[UREG_G1]); | 1058 | secure_computing(regs->u_regs[UREG_G1]); |
1056 | 1059 | ||
@@ -1064,27 +1067,14 @@ asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p) | |||
1064 | audit_syscall_exit(result, regs->u_regs[UREG_I0]); | 1067 | audit_syscall_exit(result, regs->u_regs[UREG_I0]); |
1065 | } | 1068 | } |
1066 | 1069 | ||
1067 | if (!(current->ptrace & PT_PTRACED)) | 1070 | if (test_thread_flag(TIF_SYSCALL_TRACE)) { |
1068 | goto out; | 1071 | if (syscall_exit_p) |
1069 | 1072 | tracehook_report_syscall_exit(regs, 0); | |
1070 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 1073 | else |
1071 | goto out; | 1074 | ret = tracehook_report_syscall_entry(regs); |
1072 | |||
1073 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) | ||
1074 | ? 0x80 : 0)); | ||
1075 | |||
1076 | /* | ||
1077 | * this isn't the same as continuing with a signal, but it will do | ||
1078 | * for normal use. strace only continues with a signal if the | ||
1079 | * stopping signal is not SIGTRAP. -brl | ||
1080 | */ | ||
1081 | if (current->exit_code) { | ||
1082 | send_sig(current->exit_code, current, 1); | ||
1083 | current->exit_code = 0; | ||
1084 | } | 1075 | } |
1085 | 1076 | ||
1086 | out: | 1077 | if (unlikely(current->audit_context) && !syscall_exit_p && !ret) |
1087 | if (unlikely(current->audit_context) && !syscall_exit_p) | ||
1088 | audit_syscall_entry((test_thread_flag(TIF_32BIT) ? | 1078 | audit_syscall_entry((test_thread_flag(TIF_32BIT) ? |
1089 | AUDIT_ARCH_SPARC : | 1079 | AUDIT_ARCH_SPARC : |
1090 | AUDIT_ARCH_SPARC64), | 1080 | AUDIT_ARCH_SPARC64), |
@@ -1093,4 +1083,6 @@ out: | |||
1093 | regs->u_regs[UREG_I1], | 1083 | regs->u_regs[UREG_I1], |
1094 | regs->u_regs[UREG_I2], | 1084 | regs->u_regs[UREG_I2], |
1095 | regs->u_regs[UREG_I3]); | 1085 | regs->u_regs[UREG_I3]); |
1086 | |||
1087 | return ret; | ||
1096 | } | 1088 | } |
diff --git a/arch/sparc64/kernel/syscalls.S b/arch/sparc64/kernel/syscalls.S index db19ed67acf6..a2f24270ed8a 100644 --- a/arch/sparc64/kernel/syscalls.S +++ b/arch/sparc64/kernel/syscalls.S | |||
@@ -162,6 +162,8 @@ linux_syscall_trace32: | |||
162 | add %sp, PTREGS_OFF, %o0 | 162 | add %sp, PTREGS_OFF, %o0 |
163 | call syscall_trace | 163 | call syscall_trace |
164 | clr %o1 | 164 | clr %o1 |
165 | brnz,pn %o0, 3f | ||
166 | mov -ENOSYS, %o0 | ||
165 | srl %i0, 0, %o0 | 167 | srl %i0, 0, %o0 |
166 | srl %i4, 0, %o4 | 168 | srl %i4, 0, %o4 |
167 | srl %i1, 0, %o1 | 169 | srl %i1, 0, %o1 |
@@ -173,6 +175,8 @@ linux_syscall_trace: | |||
173 | add %sp, PTREGS_OFF, %o0 | 175 | add %sp, PTREGS_OFF, %o0 |
174 | call syscall_trace | 176 | call syscall_trace |
175 | clr %o1 | 177 | clr %o1 |
178 | brnz,pn %o0, 3f | ||
179 | mov -ENOSYS, %o0 | ||
176 | mov %i0, %o0 | 180 | mov %i0, %o0 |
177 | mov %i1, %o1 | 181 | mov %i1, %o1 |
178 | mov %i2, %o2 | 182 | mov %i2, %o2 |