aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_32.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_32.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_32.c')
-rw-r--r--arch/x86/kernel/process_32.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index f8476dfbb60d..5cec8a75a4e8 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -316,6 +316,14 @@ void exit_thread(void)
316 tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; 316 tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
317 put_cpu(); 317 put_cpu();
318 } 318 }
319#ifdef CONFIG_X86_DS
320 /* Free any DS contexts that have not been properly released. */
321 if (unlikely(current->thread.ds_ctx)) {
322 /* we clear debugctl to make sure DS is not used. */
323 update_debugctlmsr(0);
324 ds_free(current->thread.ds_ctx);
325 }
326#endif /* CONFIG_X86_DS */
319} 327}
320 328
321void flush_thread(void) 329void flush_thread(void)
@@ -482,18 +490,27 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
482{ 490{
483 struct thread_struct *prev, *next; 491 struct thread_struct *prev, *next;
484 unsigned long debugctl; 492 unsigned long debugctl;
493 unsigned long ds_prev = 0, ds_next = 0;
485 494
486 prev = &prev_p->thread; 495 prev = &prev_p->thread;
487 next = &next_p->thread; 496 next = &next_p->thread;
488 497
489 debugctl = prev->debugctlmsr; 498 debugctl = prev->debugctlmsr;
490 if (next->ds_area_msr != prev->ds_area_msr) { 499
500#ifdef CONFIG_X86_DS
501 if (prev->ds_ctx)
502 ds_prev = (unsigned long)prev->ds_ctx->ds;
503 if (next->ds_ctx)
504 ds_next = (unsigned long)next->ds_ctx->ds;
505
506 if (ds_next != ds_prev) {
491 /* we clear debugctl to make sure DS 507 /* we clear debugctl to make sure DS
492 * is not in use when we change it */ 508 * is not in use when we change it */
493 debugctl = 0; 509 debugctl = 0;
494 update_debugctlmsr(0); 510 update_debugctlmsr(0);
495 wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0); 511 wrmsr(MSR_IA32_DS_AREA, ds_next, 0);
496 } 512 }
513#endif /* CONFIG_X86_DS */
497 514
498 if (next->debugctlmsr != debugctl) 515 if (next->debugctlmsr != debugctl)
499 update_debugctlmsr(next->debugctlmsr); 516 update_debugctlmsr(next->debugctlmsr);
@@ -517,13 +534,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
517 hard_enable_TSC(); 534 hard_enable_TSC();
518 } 535 }
519 536
520#ifdef X86_BTS 537#ifdef CONFIG_X86_PTRACE_BTS
521 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) 538 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
522 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); 539 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
523 540
524 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) 541 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
525 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); 542 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
526#endif 543#endif /* CONFIG_X86_PTRACE_BTS */
527 544
528 545
529 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { 546 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {