diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2008-12-19 09:10:24 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-20 03:15:46 -0500 |
commit | bf53de907dfdaac178c92d774aae7370d7b97d20 (patch) | |
tree | 738a07a8b4b22f7bb8ec2029c9ea9c635db6c62a /arch/x86/kernel/ptrace.c | |
parent | 30cd324e9787ccc9a5ede59742d5409857550692 (diff) |
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.c | 50 |
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) | |||
769 | 769 | ||
770 | return (trace->ds.top - trace->ds.begin) / trace->ds.size; | 770 | return (trace->ds.top - trace->ds.begin) / trace->ds.size; |
771 | } | 771 | } |
772 | |||
773 | static void ptrace_bts_fork(struct task_struct *tsk) | ||
774 | { | ||
775 | tsk->bts = NULL; | ||
776 | tsk->bts_buffer = NULL; | ||
777 | tsk->bts_size = 0; | ||
778 | tsk->thread.bts_ovfl_signal = 0; | ||
779 | } | ||
780 | |||
781 | static void ptrace_bts_untrace(struct task_struct *child) | ||
782 | { | ||
783 | if (unlikely(child->bts)) { | ||
784 | ds_release_bts(child->bts); | ||
785 | child->bts = NULL; | ||
786 | |||
787 | kfree(child->bts_buffer); | ||
788 | child->bts_buffer = NULL; | ||
789 | child->bts_size = 0; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | static void ptrace_bts_detach(struct task_struct *child) | ||
794 | { | ||
795 | ptrace_bts_untrace(child); | ||
796 | } | ||
797 | #else | ||
798 | static inline void ptrace_bts_fork(struct task_struct *tsk) {} | ||
799 | static inline void ptrace_bts_detach(struct task_struct *child) {} | ||
800 | static inline void ptrace_bts_untrace(struct task_struct *child) {} | ||
772 | #endif /* CONFIG_X86_PTRACE_BTS */ | 801 | #endif /* CONFIG_X86_PTRACE_BTS */ |
773 | 802 | ||
803 | void x86_ptrace_fork(struct task_struct *child, unsigned long clone_flags) | ||
804 | { | ||
805 | ptrace_bts_fork(child); | ||
806 | } | ||
807 | |||
808 | void x86_ptrace_untrace(struct task_struct *child) | ||
809 | { | ||
810 | ptrace_bts_untrace(child); | ||
811 | } | ||
812 | |||
774 | /* | 813 | /* |
775 | * Called by kernel/ptrace.c when detaching.. | 814 | * Called by kernel/ptrace.c when detaching.. |
776 | * | 815 | * |
@@ -782,16 +821,7 @@ void ptrace_disable(struct task_struct *child) | |||
782 | #ifdef TIF_SYSCALL_EMU | 821 | #ifdef TIF_SYSCALL_EMU |
783 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); | 822 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); |
784 | #endif | 823 | #endif |
785 | #ifdef CONFIG_X86_PTRACE_BTS | 824 | ptrace_bts_detach(child); |
786 | if (child->bts) { | ||
787 | ds_release_bts(child->bts); | ||
788 | child->bts = NULL; | ||
789 | |||
790 | kfree(child->bts_buffer); | ||
791 | child->bts_buffer = NULL; | ||
792 | child->bts_size = 0; | ||
793 | } | ||
794 | #endif /* CONFIG_X86_PTRACE_BTS */ | ||
795 | } | 825 | } |
796 | 826 | ||
797 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION | 827 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION |