aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ptrace.c
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2008-12-19 15:10:24 +0100
committerIngo Molnar <mingo@elte.hu>2008-12-20 09:15:46 +0100
commitbf53de907dfdaac178c92d774aae7370d7b97d20 (patch)
tree738a07a8b4b22f7bb8ec2029c9ea9c635db6c62a /arch/x86/kernel/ptrace.c
parentMerge branches 'tracing/ftrace', 'tracing/ring-buffer' and 'tracing/urgent' into tracing/core (diff)
downloadlinux-dev-bf53de907dfdaac178c92d774aae7370d7b97d20.tar.xz
linux-dev-bf53de907dfdaac178c92d774aae7370d7b97d20.zip
x86, bts: add fork and exit handling
Impact: introduce new ptrace facility Add arch_ptrace_untrace() function that is called when the tracer detaches (either voluntarily or when the tracing task dies); ptrace_disable() is only called on a voluntary detach. Add ptrace_fork() and arch_ptrace_fork(). They are called when a traced task is forked. Clear DS and BTS related fields on fork. Release DS resources and reclaim memory in ptrace_untrace(). This releases resources already when the tracing task dies. We used to do that when the traced task dies. Signed-off-by: Markus Metzger <markus.t.metzger@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
-rw-r--r--arch/x86/kernel/ptrace.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 45e9855da2d2..6ad2bb607650 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -769,8 +769,47 @@ static int ptrace_bts_size(struct task_struct *child)
return (trace->ds.top - trace->ds.begin) / trace->ds.size;
}
+
+static void ptrace_bts_fork(struct task_struct *tsk)
+{
+ tsk->bts = NULL;
+ tsk->bts_buffer = NULL;
+ tsk->bts_size = 0;
+ tsk->thread.bts_ovfl_signal = 0;
+}
+
+static void ptrace_bts_untrace(struct task_struct *child)
+{
+ if (unlikely(child->bts)) {
+ ds_release_bts(child->bts);
+ child->bts = NULL;
+
+ kfree(child->bts_buffer);
+ child->bts_buffer = NULL;
+ child->bts_size = 0;
+ }
+}
+
+static void ptrace_bts_detach(struct task_struct *child)
+{
+ ptrace_bts_untrace(child);
+}
+#else
+static inline void ptrace_bts_fork(struct task_struct *tsk) {}
+static inline void ptrace_bts_detach(struct task_struct *child) {}
+static inline void ptrace_bts_untrace(struct task_struct *child) {}
#endif /* CONFIG_X86_PTRACE_BTS */
+void x86_ptrace_fork(struct task_struct *child, unsigned long clone_flags)
+{
+ ptrace_bts_fork(child);
+}
+
+void x86_ptrace_untrace(struct task_struct *child)
+{
+ ptrace_bts_untrace(child);
+}
+
/*
* Called by kernel/ptrace.c when detaching..
*
@@ -782,16 +821,7 @@ void ptrace_disable(struct task_struct *child)
#ifdef TIF_SYSCALL_EMU
clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
#endif
-#ifdef CONFIG_X86_PTRACE_BTS
- if (child->bts) {
- ds_release_bts(child->bts);
- child->bts = NULL;
-
- kfree(child->bts_buffer);
- child->bts_buffer = NULL;
- child->bts_size = 0;
- }
-#endif /* CONFIG_X86_PTRACE_BTS */
+ ptrace_bts_detach(child);
}
#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION