diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2008-12-11 07:49:59 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-12 02:08:12 -0500 |
commit | c2724775ce57c98b8af9694857b941dc61056516 (patch) | |
tree | c3936699317da3233bc31e92d68cb582ec17d193 /arch/x86/kernel/process_32.c | |
parent | b0884e25fe361f2ca228808fb5fd1b74cb04e711 (diff) |
x86, bts: provide in-kernel branch-trace interface
Impact: cleanup
Move the BTS bits from ptrace.c into ds.c.
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/process_32.c')
-rw-r--r-- | arch/x86/kernel/process_32.c | 59 |
1 files changed, 12 insertions, 47 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 24c2276aa453..605eff9a8ac0 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -252,11 +252,14 @@ void exit_thread(void) | |||
252 | put_cpu(); | 252 | put_cpu(); |
253 | } | 253 | } |
254 | #ifdef CONFIG_X86_DS | 254 | #ifdef CONFIG_X86_DS |
255 | /* Free any DS contexts that have not been properly released. */ | 255 | /* Free any BTS tracers that have not been properly released. */ |
256 | if (unlikely(current->thread.ds_ctx)) { | 256 | if (unlikely(current->bts)) { |
257 | /* we clear debugctl to make sure DS is not used. */ | 257 | ds_release_bts(current->bts); |
258 | update_debugctlmsr(0); | 258 | current->bts = NULL; |
259 | ds_free(current->thread.ds_ctx); | 259 | |
260 | kfree(current->bts_buffer); | ||
261 | current->bts_buffer = NULL; | ||
262 | current->bts_size = 0; | ||
260 | } | 263 | } |
261 | #endif /* CONFIG_X86_DS */ | 264 | #endif /* CONFIG_X86_DS */ |
262 | } | 265 | } |
@@ -420,48 +423,19 @@ int set_tsc_mode(unsigned int val) | |||
420 | return 0; | 423 | return 0; |
421 | } | 424 | } |
422 | 425 | ||
423 | #ifdef CONFIG_X86_DS | ||
424 | static int update_debugctl(struct thread_struct *prev, | ||
425 | struct thread_struct *next, unsigned long debugctl) | ||
426 | { | ||
427 | unsigned long ds_prev = 0; | ||
428 | unsigned long ds_next = 0; | ||
429 | |||
430 | if (prev->ds_ctx) | ||
431 | ds_prev = (unsigned long)prev->ds_ctx->ds; | ||
432 | if (next->ds_ctx) | ||
433 | ds_next = (unsigned long)next->ds_ctx->ds; | ||
434 | |||
435 | if (ds_next != ds_prev) { | ||
436 | /* we clear debugctl to make sure DS | ||
437 | * is not in use when we change it */ | ||
438 | debugctl = 0; | ||
439 | update_debugctlmsr(0); | ||
440 | wrmsr(MSR_IA32_DS_AREA, ds_next, 0); | ||
441 | } | ||
442 | return debugctl; | ||
443 | } | ||
444 | #else | ||
445 | static int update_debugctl(struct thread_struct *prev, | ||
446 | struct thread_struct *next, unsigned long debugctl) | ||
447 | { | ||
448 | return debugctl; | ||
449 | } | ||
450 | #endif /* CONFIG_X86_DS */ | ||
451 | |||
452 | static noinline void | 426 | static noinline void |
453 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | 427 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, |
454 | struct tss_struct *tss) | 428 | struct tss_struct *tss) |
455 | { | 429 | { |
456 | struct thread_struct *prev, *next; | 430 | struct thread_struct *prev, *next; |
457 | unsigned long debugctl; | ||
458 | 431 | ||
459 | prev = &prev_p->thread; | 432 | prev = &prev_p->thread; |
460 | next = &next_p->thread; | 433 | next = &next_p->thread; |
461 | 434 | ||
462 | debugctl = update_debugctl(prev, next, prev->debugctlmsr); | 435 | if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) || |
463 | 436 | test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR)) | |
464 | if (next->debugctlmsr != debugctl) | 437 | ds_switch_to(prev_p, next_p); |
438 | else if (next->debugctlmsr != prev->debugctlmsr) | ||
465 | update_debugctlmsr(next->debugctlmsr); | 439 | update_debugctlmsr(next->debugctlmsr); |
466 | 440 | ||
467 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { | 441 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { |
@@ -483,15 +457,6 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
483 | hard_enable_TSC(); | 457 | hard_enable_TSC(); |
484 | } | 458 | } |
485 | 459 | ||
486 | #ifdef CONFIG_X86_PTRACE_BTS | ||
487 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | ||
488 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); | ||
489 | |||
490 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) | ||
491 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); | ||
492 | #endif /* CONFIG_X86_PTRACE_BTS */ | ||
493 | |||
494 | |||
495 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | 460 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { |
496 | /* | 461 | /* |
497 | * Disable the bitmap via an invalid offset. We still cache | 462 | * Disable the bitmap via an invalid offset. We still cache |