aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_64.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-06 10:17:23 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-06 10:17:23 -0400
commit19268ed7449c561694d048a34601a30e2d1aaf79 (patch)
tree6f3f28ddac5d2b1cecd0f18ccf283f076839532a /arch/x86/kernel/process_64.c
parentb8cd9d056bbc5f2630ab1787dbf76f83bbb517c0 (diff)
parent493cd9122af5bd0b219974a48f0e31da0c29ff7e (diff)
Merge branch 'x86/pebs' into x86-v28-for-linus-phase1
Conflicts: include/asm-x86/ds.h Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r--arch/x86/kernel/process_64.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index e12e0e4dd256..4e168b250aff 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -240,6 +240,14 @@ void exit_thread(void)
240 t->io_bitmap_max = 0; 240 t->io_bitmap_max = 0;
241 put_cpu(); 241 put_cpu();
242 } 242 }
243#ifdef CONFIG_X86_DS
244 /* Free any DS contexts that have not been properly released. */
245 if (unlikely(t->ds_ctx)) {
246 /* we clear debugctl to make sure DS is not used. */
247 update_debugctlmsr(0);
248 ds_free(t->ds_ctx);
249 }
250#endif /* CONFIG_X86_DS */
243} 251}
244 252
245void flush_thread(void) 253void flush_thread(void)
@@ -473,13 +481,27 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
473 next = &next_p->thread; 481 next = &next_p->thread;
474 482
475 debugctl = prev->debugctlmsr; 483 debugctl = prev->debugctlmsr;
476 if (next->ds_area_msr != prev->ds_area_msr) { 484
477 /* we clear debugctl to make sure DS 485#ifdef CONFIG_X86_DS
478 * is not in use when we change it */ 486 {
479 debugctl = 0; 487 unsigned long ds_prev = 0, ds_next = 0;
480 update_debugctlmsr(0); 488
481 wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr); 489 if (prev->ds_ctx)
490 ds_prev = (unsigned long)prev->ds_ctx->ds;
491 if (next->ds_ctx)
492 ds_next = (unsigned long)next->ds_ctx->ds;
493
494 if (ds_next != ds_prev) {
495 /*
496 * We clear debugctl to make sure DS
497 * is not in use when we change it:
498 */
499 debugctl = 0;
500 update_debugctlmsr(0);
501 wrmsrl(MSR_IA32_DS_AREA, ds_next);
502 }
482 } 503 }
504#endif /* CONFIG_X86_DS */
483 505
484 if (next->debugctlmsr != debugctl) 506 if (next->debugctlmsr != debugctl)
485 update_debugctlmsr(next->debugctlmsr); 507 update_debugctlmsr(next->debugctlmsr);
@@ -517,13 +539,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
517 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); 539 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
518 } 540 }
519 541
520#ifdef X86_BTS 542#ifdef CONFIG_X86_PTRACE_BTS
521 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) 543 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
522 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); 544 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
523 545
524 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) 546 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
525 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); 547 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
526#endif 548#endif /* CONFIG_X86_PTRACE_BTS */
527} 549}
528 550
529/* 551/*