Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf53de90 authored by Markus Metzger's avatar Markus Metzger Committed by Ingo Molnar
Browse files

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: default avatarMarkus Metzger <markus.t.metzger@intel.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 30cd324e
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -252,12 +252,21 @@ extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
 */
extern void ds_switch_to(struct task_struct *prev, struct task_struct *next);

/*
 * Task clone/init and cleanup work
 */
extern void ds_copy_thread(struct task_struct *tsk, struct task_struct *father);
extern void ds_exit_thread(struct task_struct *tsk);

#else /* CONFIG_X86_DS */

struct cpuinfo_x86;
static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
static inline void ds_switch_to(struct task_struct *prev,
				struct task_struct *next) {}
static inline void ds_copy_thread(struct task_struct *tsk,
				  struct task_struct *father) {}
static inline void ds_exit_thread(struct task_struct *tsk) {}

#endif /* CONFIG_X86_DS */
#endif /* _ASM_X86_DS_H */
+7 −0
Original line number Diff line number Diff line
@@ -235,6 +235,13 @@ extern int do_get_thread_area(struct task_struct *p, int idx,
extern int do_set_thread_area(struct task_struct *p, int idx,
			      struct user_desc __user *info, int can_allocate);

extern void x86_ptrace_untrace(struct task_struct *);
extern void x86_ptrace_fork(struct task_struct *child,
			    unsigned long clone_flags);

#define arch_ptrace_untrace(tsk) x86_ptrace_untrace(tsk)
#define arch_ptrace_fork(child, flags) x86_ptrace_fork(child, flags)

#endif /* __KERNEL__ */

#endif /* !__ASSEMBLY__ */
+11 −0
Original line number Diff line number Diff line
@@ -1017,3 +1017,14 @@ void ds_switch_to(struct task_struct *prev, struct task_struct *next)

	update_debugctlmsr(next->thread.debugctlmsr);
}

void ds_copy_thread(struct task_struct *tsk, struct task_struct *father)
{
	clear_tsk_thread_flag(tsk, TIF_DS_AREA_MSR);
	tsk->thread.ds_ctx = NULL;
}

void ds_exit_thread(struct task_struct *tsk)
{
	WARN_ON(tsk->thread.ds_ctx);
}
+9 −11
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@
#include <asm/idle.h>
#include <asm/syscalls.h>
#include <asm/smp.h>
#include <asm/ds.h>

asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");

@@ -251,17 +252,8 @@ void exit_thread(void)
		tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
		put_cpu();
	}
#ifdef CONFIG_X86_DS
	/* Free any BTS tracers that have not been properly released. */
	if (unlikely(current->bts)) {
		ds_release_bts(current->bts);
		current->bts = NULL;

		kfree(current->bts_buffer);
		current->bts_buffer = NULL;
		current->bts_size = 0;
	}
#endif /* CONFIG_X86_DS */
	ds_exit_thread(current);
}

void flush_thread(void)
@@ -343,6 +335,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
		kfree(p->thread.io_bitmap_ptr);
		p->thread.io_bitmap_max = 0;
	}

	ds_copy_thread(p, current);

	clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
	p->thread.debugctlmsr = 0;

	return err;
}

+9 −11
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@
#include <asm/ia32.h>
#include <asm/idle.h>
#include <asm/syscalls.h>
#include <asm/ds.h>

asmlinkage extern void ret_from_fork(void);

@@ -236,17 +237,8 @@ void exit_thread(void)
		t->io_bitmap_max = 0;
		put_cpu();
	}
#ifdef CONFIG_X86_DS
	/* Free any BTS tracers that have not been properly released. */
	if (unlikely(current->bts)) {
		ds_release_bts(current->bts);
		current->bts = NULL;

		kfree(current->bts_buffer);
		current->bts_buffer = NULL;
		current->bts_size = 0;
	}
#endif /* CONFIG_X86_DS */
	ds_exit_thread(current);
}

void flush_thread(void)
@@ -376,6 +368,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
		if (err)
			goto out;
	}

	ds_copy_thread(p, me);

	clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
	p->thread.debugctlmsr = 0;

	err = 0;
out:
	if (err && p->thread.io_bitmap_ptr) {
Loading