diff options
author | Shaohua Li <shaohua.li@intel.com> | 2008-10-06 13:43:06 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2008-10-06 13:43:06 -0400 |
commit | f14488ccfe0f41207e40520fab60dce356ed9e57 (patch) | |
tree | ef538012500f197397fbee674591910a96a50805 /arch | |
parent | cfb361f13c8136de78c406745abc4e4456e6d480 (diff) |
[IA64] utrace use generic trace hook
Make IA64 use generic trace hook in some paths.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/ia32/ia32_entry.S | 5 | ||||
-rw-r--r-- | arch/ia64/include/asm/thread_info.h | 3 | ||||
-rw-r--r-- | arch/ia64/kernel/entry.S | 5 | ||||
-rw-r--r-- | arch/ia64/kernel/perfmon.c | 7 | ||||
-rw-r--r-- | arch/ia64/kernel/process.c | 21 | ||||
-rw-r--r-- | arch/ia64/kernel/ptrace.c | 47 | ||||
-rw-r--r-- | arch/ia64/kernel/signal.c | 8 |
7 files changed, 41 insertions, 55 deletions
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index ff88c48c5d19..b905dcb791ff 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S | |||
@@ -108,6 +108,11 @@ GLOBAL_ENTRY(ia32_trace_syscall) | |||
108 | ;; | 108 | ;; |
109 | st8 [r2]=r3 // initialize return code to -ENOSYS | 109 | st8 [r2]=r3 // initialize return code to -ENOSYS |
110 | br.call.sptk.few rp=syscall_trace_enter // give parent a chance to catch syscall args | 110 | br.call.sptk.few rp=syscall_trace_enter // give parent a chance to catch syscall args |
111 | cmp.lt p6,p0=r8,r0 // check tracehook | ||
112 | adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 | ||
113 | ;; | ||
114 | (p6) st8.spill [r2]=r8 // store return value in slot for r8 | ||
115 | (p6) br.spnt.few .ret4 | ||
111 | .ret2: // Need to reload arguments (they may be changed by the tracing process) | 116 | .ret2: // Need to reload arguments (they may be changed by the tracing process) |
112 | adds r2=IA64_PT_REGS_R1_OFFSET+16,sp // r2 = &pt_regs.r1 | 117 | adds r2=IA64_PT_REGS_R1_OFFSET+16,sp // r2 = &pt_regs.r1 |
113 | adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 | 118 | adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 |
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index 7c60fcdd2efd..ae6922626bf4 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h | |||
@@ -87,9 +87,6 @@ struct thread_info { | |||
87 | #define alloc_task_struct() ((struct task_struct *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER)) | 87 | #define alloc_task_struct() ((struct task_struct *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER)) |
88 | #define free_task_struct(tsk) free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER) | 88 | #define free_task_struct(tsk) free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER) |
89 | 89 | ||
90 | #define tsk_set_notify_resume(tsk) \ | ||
91 | set_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME) | ||
92 | extern void tsk_clear_notify_resume(struct task_struct *tsk); | ||
93 | #endif /* !__ASSEMBLY */ | 90 | #endif /* !__ASSEMBLY */ |
94 | 91 | ||
95 | /* | 92 | /* |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 0dd6c1419d8d..7ef0c594f5ed 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -534,6 +534,11 @@ GLOBAL_ENTRY(ia64_trace_syscall) | |||
534 | stf.spill [r16]=f10 | 534 | stf.spill [r16]=f10 |
535 | stf.spill [r17]=f11 | 535 | stf.spill [r17]=f11 |
536 | br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args | 536 | br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args |
537 | cmp.lt p6,p0=r8,r0 // check tracehook | ||
538 | adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 | ||
539 | adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10 | ||
540 | mov r10=0 | ||
541 | (p6) br.cond.sptk strace_error // syscall failed -> | ||
537 | adds r16=PT(F6)+16,sp | 542 | adds r16=PT(F6)+16,sp |
538 | adds r17=PT(F7)+16,sp | 543 | adds r17=PT(F7)+16,sp |
539 | ;; | 544 | ;; |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index fc8f3509df27..ada4605d1223 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/capability.h> | 40 | #include <linux/capability.h> |
41 | #include <linux/rcupdate.h> | 41 | #include <linux/rcupdate.h> |
42 | #include <linux/completion.h> | 42 | #include <linux/completion.h> |
43 | #include <linux/tracehook.h> | ||
43 | 44 | ||
44 | #include <asm/errno.h> | 45 | #include <asm/errno.h> |
45 | #include <asm/intrinsics.h> | 46 | #include <asm/intrinsics.h> |
@@ -3684,7 +3685,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) | |||
3684 | 3685 | ||
3685 | PFM_SET_WORK_PENDING(task, 1); | 3686 | PFM_SET_WORK_PENDING(task, 1); |
3686 | 3687 | ||
3687 | tsk_set_notify_resume(task); | 3688 | set_notify_resume(task); |
3688 | 3689 | ||
3689 | /* | 3690 | /* |
3690 | * XXX: send reschedule if task runs on another CPU | 3691 | * XXX: send reschedule if task runs on another CPU |
@@ -5044,8 +5045,6 @@ pfm_handle_work(void) | |||
5044 | 5045 | ||
5045 | PFM_SET_WORK_PENDING(current, 0); | 5046 | PFM_SET_WORK_PENDING(current, 0); |
5046 | 5047 | ||
5047 | tsk_clear_notify_resume(current); | ||
5048 | |||
5049 | regs = task_pt_regs(current); | 5048 | regs = task_pt_regs(current); |
5050 | 5049 | ||
5051 | /* | 5050 | /* |
@@ -5414,7 +5413,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str | |||
5414 | * when coming from ctxsw, current still points to the | 5413 | * when coming from ctxsw, current still points to the |
5415 | * previous task, therefore we must work with task and not current. | 5414 | * previous task, therefore we must work with task and not current. |
5416 | */ | 5415 | */ |
5417 | tsk_set_notify_resume(task); | 5416 | set_notify_resume(task); |
5418 | } | 5417 | } |
5419 | /* | 5418 | /* |
5420 | * defer until state is changed (shorten spin window). the context is locked | 5419 | * defer until state is changed (shorten spin window). the context is locked |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 3ab8373103ec..341a0319a5ba 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/kdebug.h> | 29 | #include <linux/kdebug.h> |
30 | #include <linux/utsname.h> | 30 | #include <linux/utsname.h> |
31 | #include <linux/tracehook.h> | ||
31 | 32 | ||
32 | #include <asm/cpu.h> | 33 | #include <asm/cpu.h> |
33 | #include <asm/delay.h> | 34 | #include <asm/delay.h> |
@@ -160,21 +161,6 @@ show_regs (struct pt_regs *regs) | |||
160 | show_stack(NULL, NULL); | 161 | show_stack(NULL, NULL); |
161 | } | 162 | } |
162 | 163 | ||
163 | void tsk_clear_notify_resume(struct task_struct *tsk) | ||
164 | { | ||
165 | #ifdef CONFIG_PERFMON | ||
166 | if (tsk->thread.pfm_needs_checking) | ||
167 | return; | ||
168 | #endif | ||
169 | if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE)) | ||
170 | return; | ||
171 | clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME); | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * do_notify_resume_user(): | ||
176 | * Called from notify_resume_user at entry.S, with interrupts disabled. | ||
177 | */ | ||
178 | void | 164 | void |
179 | do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) | 165 | do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) |
180 | { | 166 | { |
@@ -203,6 +189,11 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) | |||
203 | ia64_do_signal(scr, in_syscall); | 189 | ia64_do_signal(scr, in_syscall); |
204 | } | 190 | } |
205 | 191 | ||
192 | if (test_thread_flag(TIF_NOTIFY_RESUME)) { | ||
193 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
194 | tracehook_notify_resume(&scr->pt); | ||
195 | } | ||
196 | |||
206 | /* copy user rbs to kernel rbs */ | 197 | /* copy user rbs to kernel rbs */ |
207 | if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) { | 198 | if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) { |
208 | local_irq_enable(); /* force interrupt enable */ | 199 | local_irq_enable(); /* force interrupt enable */ |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 12b1e9f0b7ae..92c9689b7d97 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/signal.h> | 22 | #include <linux/signal.h> |
23 | #include <linux/regset.h> | 23 | #include <linux/regset.h> |
24 | #include <linux/elf.h> | 24 | #include <linux/elf.h> |
25 | #include <linux/tracehook.h> | ||
25 | 26 | ||
26 | #include <asm/pgtable.h> | 27 | #include <asm/pgtable.h> |
27 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
@@ -603,7 +604,7 @@ void ia64_ptrace_stop(void) | |||
603 | { | 604 | { |
604 | if (test_and_set_tsk_thread_flag(current, TIF_RESTORE_RSE)) | 605 | if (test_and_set_tsk_thread_flag(current, TIF_RESTORE_RSE)) |
605 | return; | 606 | return; |
606 | tsk_set_notify_resume(current); | 607 | set_notify_resume(current); |
607 | unw_init_running(do_sync_rbs, ia64_sync_user_rbs); | 608 | unw_init_running(do_sync_rbs, ia64_sync_user_rbs); |
608 | } | 609 | } |
609 | 610 | ||
@@ -613,7 +614,6 @@ void ia64_ptrace_stop(void) | |||
613 | void ia64_sync_krbs(void) | 614 | void ia64_sync_krbs(void) |
614 | { | 615 | { |
615 | clear_tsk_thread_flag(current, TIF_RESTORE_RSE); | 616 | clear_tsk_thread_flag(current, TIF_RESTORE_RSE); |
616 | tsk_clear_notify_resume(current); | ||
617 | 617 | ||
618 | unw_init_running(do_sync_rbs, ia64_sync_kernel_rbs); | 618 | unw_init_running(do_sync_rbs, ia64_sync_kernel_rbs); |
619 | } | 619 | } |
@@ -644,7 +644,7 @@ ptrace_attach_sync_user_rbs (struct task_struct *child) | |||
644 | spin_lock_irq(&child->sighand->siglock); | 644 | spin_lock_irq(&child->sighand->siglock); |
645 | if (child->state == TASK_STOPPED && | 645 | if (child->state == TASK_STOPPED && |
646 | !test_and_set_tsk_thread_flag(child, TIF_RESTORE_RSE)) { | 646 | !test_and_set_tsk_thread_flag(child, TIF_RESTORE_RSE)) { |
647 | tsk_set_notify_resume(child); | 647 | set_notify_resume(child); |
648 | 648 | ||
649 | child->state = TASK_TRACED; | 649 | child->state = TASK_TRACED; |
650 | stopped = 1; | 650 | stopped = 1; |
@@ -1232,37 +1232,16 @@ arch_ptrace (struct task_struct *child, long request, long addr, long data) | |||
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | 1234 | ||
1235 | static void | ||
1236 | syscall_trace (void) | ||
1237 | { | ||
1238 | /* | ||
1239 | * The 0x80 provides a way for the tracing parent to | ||
1240 | * distinguish between a syscall stop and SIGTRAP delivery. | ||
1241 | */ | ||
1242 | ptrace_notify(SIGTRAP | ||
1243 | | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); | ||
1244 | |||
1245 | /* | ||
1246 | * This isn't the same as continuing with a signal, but it | ||
1247 | * will do for normal use. strace only continues with a | ||
1248 | * signal if the stopping signal is not SIGTRAP. -brl | ||
1249 | */ | ||
1250 | if (current->exit_code) { | ||
1251 | send_sig(current->exit_code, current, 1); | ||
1252 | current->exit_code = 0; | ||
1253 | } | ||
1254 | } | ||
1255 | |||
1256 | /* "asmlinkage" so the input arguments are preserved... */ | 1235 | /* "asmlinkage" so the input arguments are preserved... */ |
1257 | 1236 | ||
1258 | asmlinkage void | 1237 | asmlinkage long |
1259 | syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, | 1238 | syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, |
1260 | long arg4, long arg5, long arg6, long arg7, | 1239 | long arg4, long arg5, long arg6, long arg7, |
1261 | struct pt_regs regs) | 1240 | struct pt_regs regs) |
1262 | { | 1241 | { |
1263 | if (test_thread_flag(TIF_SYSCALL_TRACE) | 1242 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
1264 | && (current->ptrace & PT_PTRACED)) | 1243 | if (tracehook_report_syscall_entry(®s)) |
1265 | syscall_trace(); | 1244 | return -ENOSYS; |
1266 | 1245 | ||
1267 | /* copy user rbs to kernel rbs */ | 1246 | /* copy user rbs to kernel rbs */ |
1268 | if (test_thread_flag(TIF_RESTORE_RSE)) | 1247 | if (test_thread_flag(TIF_RESTORE_RSE)) |
@@ -1283,6 +1262,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, | |||
1283 | audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3); | 1262 | audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3); |
1284 | } | 1263 | } |
1285 | 1264 | ||
1265 | return 0; | ||
1286 | } | 1266 | } |
1287 | 1267 | ||
1288 | /* "asmlinkage" so the input arguments are preserved... */ | 1268 | /* "asmlinkage" so the input arguments are preserved... */ |
@@ -1292,6 +1272,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, | |||
1292 | long arg4, long arg5, long arg6, long arg7, | 1272 | long arg4, long arg5, long arg6, long arg7, |
1293 | struct pt_regs regs) | 1273 | struct pt_regs regs) |
1294 | { | 1274 | { |
1275 | int step; | ||
1276 | |||
1295 | if (unlikely(current->audit_context)) { | 1277 | if (unlikely(current->audit_context)) { |
1296 | int success = AUDITSC_RESULT(regs.r10); | 1278 | int success = AUDITSC_RESULT(regs.r10); |
1297 | long result = regs.r8; | 1279 | long result = regs.r8; |
@@ -1301,10 +1283,9 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, | |||
1301 | audit_syscall_exit(success, result); | 1283 | audit_syscall_exit(success, result); |
1302 | } | 1284 | } |
1303 | 1285 | ||
1304 | if ((test_thread_flag(TIF_SYSCALL_TRACE) | 1286 | step = test_thread_flag(TIF_SINGLESTEP); |
1305 | || test_thread_flag(TIF_SINGLESTEP)) | 1287 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) |
1306 | && (current->ptrace & PT_PTRACED)) | 1288 | tracehook_report_syscall_exit(®s, step); |
1307 | syscall_trace(); | ||
1308 | 1289 | ||
1309 | /* copy user rbs to kernel rbs */ | 1290 | /* copy user rbs to kernel rbs */ |
1310 | if (test_thread_flag(TIF_RESTORE_RSE)) | 1291 | if (test_thread_flag(TIF_RESTORE_RSE)) |
@@ -1940,7 +1921,7 @@ gpregs_writeback(struct task_struct *target, | |||
1940 | { | 1921 | { |
1941 | if (test_and_set_tsk_thread_flag(target, TIF_RESTORE_RSE)) | 1922 | if (test_and_set_tsk_thread_flag(target, TIF_RESTORE_RSE)) |
1942 | return 0; | 1923 | return 0; |
1943 | tsk_set_notify_resume(target); | 1924 | set_notify_resume(target); |
1944 | return do_regset_call(do_gpregs_writeback, target, regset, 0, 0, | 1925 | return do_regset_call(do_gpregs_writeback, target, regset, 0, 0, |
1945 | NULL, NULL); | 1926 | NULL, NULL); |
1946 | } | 1927 | } |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 19c5a78636fc..e12500a9c443 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
13 | #include <linux/ptrace.h> | 13 | #include <linux/ptrace.h> |
14 | #include <linux/tracehook.h> | ||
14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
15 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
16 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
@@ -439,6 +440,13 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse | |||
439 | sigaddset(¤t->blocked, sig); | 440 | sigaddset(¤t->blocked, sig); |
440 | recalc_sigpending(); | 441 | recalc_sigpending(); |
441 | spin_unlock_irq(¤t->sighand->siglock); | 442 | spin_unlock_irq(¤t->sighand->siglock); |
443 | |||
444 | /* | ||
445 | * Let tracing know that we've done the handler setup. | ||
446 | */ | ||
447 | tracehook_signal_handler(sig, info, ka, &scr->pt, | ||
448 | test_thread_flag(TIF_SINGLESTEP)); | ||
449 | |||
442 | return 1; | 450 | return 1; |
443 | } | 451 | } |
444 | 452 | ||