aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_64.c
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2008-04-08 05:01:58 -0400
committerIngo Molnar <mingo@elte.hu>2008-05-12 15:27:53 -0400
commit93fa7636dfdc059b25df148f230c0991096afdef (patch)
treecf277bd09091ac69abb5f7fdc21c705b8f186f88 /arch/x86/kernel/process_64.c
parent492c2e476eac010962850006c49df326919b284c (diff)
x86, ptrace: PEBS support
Polish the ds.h interface and add support for PEBS. Ds.c is meant to be the resource allocator for per-thread and per-cpu BTS and PEBS recording. It is used by ptrace/utrace to provide execution tracing of debugged tasks. It will be used by profilers (e.g. perfmon2). It may be used by kernel debuggers to provide a kernel execution trace. Changes in detail: - guard DS and ptrace by CONFIG macros - separate DS and BTS more clearly - simplify field accesses - add functions to manage PEBS buffers - add simple protection/allocation mechanism - added support for Atom Opens: - buffer overflow handling Currently, only circular buffers are supported. This is all we need for debugging. Profilers would want an overflow notification. This is planned to be added when perfmon2 is made to use the ds.h interface. - utrace intermediate layer Signed-off-by: Markus Metzger <markus.t.metzger@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r--arch/x86/kernel/process_64.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index e2319f39988..ad213494a22 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -267,6 +267,14 @@ void exit_thread(void)
267 t->io_bitmap_max = 0; 267 t->io_bitmap_max = 0;
268 put_cpu(); 268 put_cpu();
269 } 269 }
270#ifdef CONFIG_X86_DS
271 /* Free any DS contexts that have not been properly released. */
272 if (unlikely(t->ds_ctx)) {
273 /* we clear debugctl to make sure DS is not used. */
274 update_debugctlmsr(0);
275 ds_free(t->ds_ctx);
276 }
277#endif /* CONFIG_X86_DS */
270} 278}
271 279
272void flush_thread(void) 280void flush_thread(void)
@@ -492,18 +500,27 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
492{ 500{
493 struct thread_struct *prev, *next; 501 struct thread_struct *prev, *next;
494 unsigned long debugctl; 502 unsigned long debugctl;
503 unsigned long ds_prev = 0, ds_next = 0;
495 504
496 prev = &prev_p->thread, 505 prev = &prev_p->thread,
497 next = &next_p->thread; 506 next = &next_p->thread;
498 507
499 debugctl = prev->debugctlmsr; 508 debugctl = prev->debugctlmsr;
500 if (next->ds_area_msr != prev->ds_area_msr) { 509
510#ifdef CONFIG_X86_DS
511 if (prev->ds_ctx)
512 ds_prev = (unsigned long)prev->ds_ctx->ds;
513 if (next->ds_ctx)
514 ds_next = (unsigned long)next->ds_ctx->ds;
515
516 if (ds_next != ds_prev) {
501 /* we clear debugctl to make sure DS 517 /* we clear debugctl to make sure DS
502 * is not in use when we change it */ 518 * is not in use when we change it */
503 debugctl = 0; 519 debugctl = 0;
504 update_debugctlmsr(0); 520 update_debugctlmsr(0);
505 wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr); 521 wrmsrl(MSR_IA32_DS_AREA, ds_next);
506 } 522 }
523#endif /* CONFIG_X86_DS */
507 524
508 if (next->debugctlmsr != debugctl) 525 if (next->debugctlmsr != debugctl)
509 update_debugctlmsr(next->debugctlmsr); 526 update_debugctlmsr(next->debugctlmsr);
@@ -541,13 +558,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
541 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); 558 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
542 } 559 }
543 560
544#ifdef X86_BTS 561#ifdef CONFIG_X86_PTRACE_BTS
545 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) 562 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
546 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); 563 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
547 564
548 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) 565 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
549 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); 566 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
550#endif 567#endif /* CONFIG_X86_PTRACE_BTS */
551} 568}
552 569
553/* 570/*