diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-06 10:17:23 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-06 10:17:23 -0400 |
commit | 19268ed7449c561694d048a34601a30e2d1aaf79 (patch) | |
tree | 6f3f28ddac5d2b1cecd0f18ccf283f076839532a /arch/x86/kernel/process_32.c | |
parent | b8cd9d056bbc5f2630ab1787dbf76f83bbb517c0 (diff) | |
parent | 493cd9122af5bd0b219974a48f0e31da0c29ff7e (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_32.c')
-rw-r--r-- | arch/x86/kernel/process_32.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 31f40b24bf5d..491eb1a7e073 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -277,6 +277,14 @@ void exit_thread(void) | |||
277 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | 277 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; |
278 | put_cpu(); | 278 | put_cpu(); |
279 | } | 279 | } |
280 | #ifdef CONFIG_X86_DS | ||
281 | /* Free any DS contexts that have not been properly released. */ | ||
282 | if (unlikely(current->thread.ds_ctx)) { | ||
283 | /* we clear debugctl to make sure DS is not used. */ | ||
284 | update_debugctlmsr(0); | ||
285 | ds_free(current->thread.ds_ctx); | ||
286 | } | ||
287 | #endif /* CONFIG_X86_DS */ | ||
280 | } | 288 | } |
281 | 289 | ||
282 | void flush_thread(void) | 290 | void flush_thread(void) |
@@ -438,6 +446,35 @@ int set_tsc_mode(unsigned int val) | |||
438 | return 0; | 446 | return 0; |
439 | } | 447 | } |
440 | 448 | ||
449 | #ifdef CONFIG_X86_DS | ||
450 | static int update_debugctl(struct thread_struct *prev, | ||
451 | struct thread_struct *next, unsigned long debugctl) | ||
452 | { | ||
453 | unsigned long ds_prev = 0; | ||
454 | unsigned long ds_next = 0; | ||
455 | |||
456 | if (prev->ds_ctx) | ||
457 | ds_prev = (unsigned long)prev->ds_ctx->ds; | ||
458 | if (next->ds_ctx) | ||
459 | ds_next = (unsigned long)next->ds_ctx->ds; | ||
460 | |||
461 | if (ds_next != ds_prev) { | ||
462 | /* we clear debugctl to make sure DS | ||
463 | * is not in use when we change it */ | ||
464 | debugctl = 0; | ||
465 | update_debugctlmsr(0); | ||
466 | wrmsr(MSR_IA32_DS_AREA, ds_next, 0); | ||
467 | } | ||
468 | return debugctl; | ||
469 | } | ||
470 | #else | ||
471 | static int update_debugctl(struct thread_struct *prev, | ||
472 | struct thread_struct *next, unsigned long debugctl) | ||
473 | { | ||
474 | return debugctl; | ||
475 | } | ||
476 | #endif /* CONFIG_X86_DS */ | ||
477 | |||
441 | static noinline void | 478 | static noinline void |
442 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | 479 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, |
443 | struct tss_struct *tss) | 480 | struct tss_struct *tss) |
@@ -448,14 +485,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
448 | prev = &prev_p->thread; | 485 | prev = &prev_p->thread; |
449 | next = &next_p->thread; | 486 | next = &next_p->thread; |
450 | 487 | ||
451 | debugctl = prev->debugctlmsr; | 488 | debugctl = update_debugctl(prev, next, prev->debugctlmsr); |
452 | if (next->ds_area_msr != prev->ds_area_msr) { | ||
453 | /* we clear debugctl to make sure DS | ||
454 | * is not in use when we change it */ | ||
455 | debugctl = 0; | ||
456 | update_debugctlmsr(0); | ||
457 | wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0); | ||
458 | } | ||
459 | 489 | ||
460 | if (next->debugctlmsr != debugctl) | 490 | if (next->debugctlmsr != debugctl) |
461 | update_debugctlmsr(next->debugctlmsr); | 491 | update_debugctlmsr(next->debugctlmsr); |
@@ -479,13 +509,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
479 | hard_enable_TSC(); | 509 | hard_enable_TSC(); |
480 | } | 510 | } |
481 | 511 | ||
482 | #ifdef X86_BTS | 512 | #ifdef CONFIG_X86_PTRACE_BTS |
483 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | 513 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) |
484 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); | 514 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); |
485 | 515 | ||
486 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) | 516 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) |
487 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); | 517 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); |
488 | #endif | 518 | #endif /* CONFIG_X86_PTRACE_BTS */ |
489 | 519 | ||
490 | 520 | ||
491 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | 521 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { |