diff options
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r-- | arch/x86/kernel/process_64.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 00263c9e6500..08a9df08adba 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -239,6 +239,14 @@ void exit_thread(void) | |||
239 | t->io_bitmap_max = 0; | 239 | t->io_bitmap_max = 0; |
240 | put_cpu(); | 240 | put_cpu(); |
241 | } | 241 | } |
242 | #ifdef CONFIG_X86_DS | ||
243 | /* Free any DS contexts that have not been properly released. */ | ||
244 | if (unlikely(t->ds_ctx)) { | ||
245 | /* we clear debugctl to make sure DS is not used. */ | ||
246 | update_debugctlmsr(0); | ||
247 | ds_free(t->ds_ctx); | ||
248 | } | ||
249 | #endif /* CONFIG_X86_DS */ | ||
242 | } | 250 | } |
243 | 251 | ||
244 | void flush_thread(void) | 252 | void flush_thread(void) |
@@ -472,13 +480,27 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
472 | next = &next_p->thread; | 480 | next = &next_p->thread; |
473 | 481 | ||
474 | debugctl = prev->debugctlmsr; | 482 | debugctl = prev->debugctlmsr; |
475 | if (next->ds_area_msr != prev->ds_area_msr) { | 483 | |
476 | /* we clear debugctl to make sure DS | 484 | #ifdef CONFIG_X86_DS |
477 | * is not in use when we change it */ | 485 | { |
478 | debugctl = 0; | 486 | unsigned long ds_prev = 0, ds_next = 0; |
479 | update_debugctlmsr(0); | 487 | |
480 | wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr); | 488 | if (prev->ds_ctx) |
489 | ds_prev = (unsigned long)prev->ds_ctx->ds; | ||
490 | if (next->ds_ctx) | ||
491 | ds_next = (unsigned long)next->ds_ctx->ds; | ||
492 | |||
493 | if (ds_next != ds_prev) { | ||
494 | /* | ||
495 | * We clear debugctl to make sure DS | ||
496 | * is not in use when we change it: | ||
497 | */ | ||
498 | debugctl = 0; | ||
499 | update_debugctlmsr(0); | ||
500 | wrmsrl(MSR_IA32_DS_AREA, ds_next); | ||
501 | } | ||
481 | } | 502 | } |
503 | #endif /* CONFIG_X86_DS */ | ||
482 | 504 | ||
483 | if (next->debugctlmsr != debugctl) | 505 | if (next->debugctlmsr != debugctl) |
484 | update_debugctlmsr(next->debugctlmsr); | 506 | update_debugctlmsr(next->debugctlmsr); |
@@ -516,13 +538,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
516 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); | 538 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); |
517 | } | 539 | } |
518 | 540 | ||
519 | #ifdef X86_BTS | 541 | #ifdef CONFIG_X86_PTRACE_BTS |
520 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | 542 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) |
521 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); | 543 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); |
522 | 544 | ||
523 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) | 545 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) |
524 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); | 546 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); |
525 | #endif | 547 | #endif /* CONFIG_X86_PTRACE_BTS */ |
526 | } | 548 | } |
527 | 549 | ||
528 | /* | 550 | /* |