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

Commit 19268ed7 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'x86/pebs' into x86-v28-for-linus-phase1



Conflicts:
	include/asm-x86/ds.h

Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parents b8cd9d05 493cd912
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -418,3 +418,21 @@ config X86_MINIMUM_CPU_FAMILY
config X86_DEBUGCTLMSR
	def_bool y
	depends on !(MK6 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386)

config X86_DS
	bool "Debug Store support"
	default y
	help
	  Add support for Debug Store.
	  This allows the kernel to provide a memory buffer to the hardware
	  to store various profiling and tracing events.

config X86_PTRACE_BTS
	bool "ptrace interface to Branch Trace Store"
	default y
	depends on (X86_DS && X86_DEBUGCTLMSR)
	help
	  Add a ptrace interface to allow collecting an execution trace
	  of the traced task.
	  This collects control flow changes in a (cyclic) buffer and allows
	  debuggers to fill in the gaps and show an execution trace of the debuggee.
+2 −1
Original line number Diff line number Diff line
@@ -222,10 +222,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
			set_cpu_cap(c, X86_FEATURE_BTS);
		if (!(l1 & (1<<12)))
			set_cpu_cap(c, X86_FEATURE_PEBS);
		ds_init_intel(c);
	}

	if (cpu_has_bts)
		ds_init_intel(c);
		ptrace_bts_init_intel(c);

	/*
	 * See if we have a good local APIC by checking for buggy Pentia,
+677 −277

File changed.

Preview size limit exceeded, changes collapsed.

+40 −10
Original line number Diff line number Diff line
@@ -277,6 +277,14 @@ void exit_thread(void)
		tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
		put_cpu();
	}
#ifdef CONFIG_X86_DS
	/* Free any DS contexts that have not been properly released. */
	if (unlikely(current->thread.ds_ctx)) {
		/* we clear debugctl to make sure DS is not used. */
		update_debugctlmsr(0);
		ds_free(current->thread.ds_ctx);
	}
#endif /* CONFIG_X86_DS */
}

void flush_thread(void)
@@ -438,6 +446,35 @@ int set_tsc_mode(unsigned int val)
	return 0;
}

#ifdef CONFIG_X86_DS
static int update_debugctl(struct thread_struct *prev,
			struct thread_struct *next, unsigned long debugctl)
{
	unsigned long ds_prev = 0;
	unsigned long ds_next = 0;

	if (prev->ds_ctx)
		ds_prev = (unsigned long)prev->ds_ctx->ds;
	if (next->ds_ctx)
		ds_next = (unsigned long)next->ds_ctx->ds;

	if (ds_next != ds_prev) {
		/* we clear debugctl to make sure DS
		 * is not in use when we change it */
		debugctl = 0;
		update_debugctlmsr(0);
		wrmsr(MSR_IA32_DS_AREA, ds_next, 0);
	}
	return debugctl;
}
#else
static int update_debugctl(struct thread_struct *prev,
			struct thread_struct *next, unsigned long debugctl)
{
	return debugctl;
}
#endif /* CONFIG_X86_DS */

static noinline void
__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
		 struct tss_struct *tss)
@@ -448,14 +485,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
	prev = &prev_p->thread;
	next = &next_p->thread;

	debugctl = prev->debugctlmsr;
	if (next->ds_area_msr != prev->ds_area_msr) {
		/* we clear debugctl to make sure DS
		 * is not in use when we change it */
		debugctl = 0;
		update_debugctlmsr(0);
		wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0);
	}
	debugctl = update_debugctl(prev, next, prev->debugctlmsr);

	if (next->debugctlmsr != debugctl)
		update_debugctlmsr(next->debugctlmsr);
@@ -479,13 +509,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
			hard_enable_TSC();
	}

#ifdef X86_BTS
#ifdef CONFIG_X86_PTRACE_BTS
	if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
		ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);

	if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
		ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
#endif
#endif /* CONFIG_X86_PTRACE_BTS */


	if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
+30 −8
Original line number Diff line number Diff line
@@ -240,6 +240,14 @@ void exit_thread(void)
		t->io_bitmap_max = 0;
		put_cpu();
	}
#ifdef CONFIG_X86_DS
	/* Free any DS contexts that have not been properly released. */
	if (unlikely(t->ds_ctx)) {
		/* we clear debugctl to make sure DS is not used. */
		update_debugctlmsr(0);
		ds_free(t->ds_ctx);
	}
#endif /* CONFIG_X86_DS */
}

void flush_thread(void)
@@ -473,13 +481,27 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
	next = &next_p->thread;

	debugctl = prev->debugctlmsr;
	if (next->ds_area_msr != prev->ds_area_msr) {
		/* we clear debugctl to make sure DS
		 * is not in use when we change it */

#ifdef CONFIG_X86_DS
	{
		unsigned long ds_prev = 0, ds_next = 0;

		if (prev->ds_ctx)
			ds_prev = (unsigned long)prev->ds_ctx->ds;
		if (next->ds_ctx)
			ds_next = (unsigned long)next->ds_ctx->ds;

		if (ds_next != ds_prev) {
			/*
			 * We clear debugctl to make sure DS
			 * is not in use when we change it:
			 */
			debugctl = 0;
			update_debugctlmsr(0);
		wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr);
			wrmsrl(MSR_IA32_DS_AREA, ds_next);
		}
	}
#endif /* CONFIG_X86_DS */

	if (next->debugctlmsr != debugctl)
		update_debugctlmsr(next->debugctlmsr);
@@ -517,13 +539,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
		memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
	}

#ifdef X86_BTS
#ifdef CONFIG_X86_PTRACE_BTS
	if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
		ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);

	if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
		ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
#endif
#endif /* CONFIG_X86_PTRACE_BTS */
}

/*
Loading