diff options
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r-- | arch/x86/kernel/process_64.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e2319f39988b..ad213494a22f 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -267,6 +267,14 @@ void exit_thread(void) | |||
267 | t->io_bitmap_max = 0; | 267 | t->io_bitmap_max = 0; |
268 | put_cpu(); | 268 | put_cpu(); |
269 | } | 269 | } |
270 | #ifdef CONFIG_X86_DS | ||
271 | /* Free any DS contexts that have not been properly released. */ | ||
272 | if (unlikely(t->ds_ctx)) { | ||
273 | /* we clear debugctl to make sure DS is not used. */ | ||
274 | update_debugctlmsr(0); | ||
275 | ds_free(t->ds_ctx); | ||
276 | } | ||
277 | #endif /* CONFIG_X86_DS */ | ||
270 | } | 278 | } |
271 | 279 | ||
272 | void flush_thread(void) | 280 | void flush_thread(void) |
@@ -492,18 +500,27 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
492 | { | 500 | { |
493 | struct thread_struct *prev, *next; | 501 | struct thread_struct *prev, *next; |
494 | unsigned long debugctl; | 502 | unsigned long debugctl; |
503 | unsigned long ds_prev = 0, ds_next = 0; | ||
495 | 504 | ||
496 | prev = &prev_p->thread, | 505 | prev = &prev_p->thread, |
497 | next = &next_p->thread; | 506 | next = &next_p->thread; |
498 | 507 | ||
499 | debugctl = prev->debugctlmsr; | 508 | debugctl = prev->debugctlmsr; |
500 | if (next->ds_area_msr != prev->ds_area_msr) { | 509 | |
510 | #ifdef CONFIG_X86_DS | ||
511 | if (prev->ds_ctx) | ||
512 | ds_prev = (unsigned long)prev->ds_ctx->ds; | ||
513 | if (next->ds_ctx) | ||
514 | ds_next = (unsigned long)next->ds_ctx->ds; | ||
515 | |||
516 | if (ds_next != ds_prev) { | ||
501 | /* we clear debugctl to make sure DS | 517 | /* we clear debugctl to make sure DS |
502 | * is not in use when we change it */ | 518 | * is not in use when we change it */ |
503 | debugctl = 0; | 519 | debugctl = 0; |
504 | update_debugctlmsr(0); | 520 | update_debugctlmsr(0); |
505 | wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr); | 521 | wrmsrl(MSR_IA32_DS_AREA, ds_next); |
506 | } | 522 | } |
523 | #endif /* CONFIG_X86_DS */ | ||
507 | 524 | ||
508 | if (next->debugctlmsr != debugctl) | 525 | if (next->debugctlmsr != debugctl) |
509 | update_debugctlmsr(next->debugctlmsr); | 526 | update_debugctlmsr(next->debugctlmsr); |
@@ -541,13 +558,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
541 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); | 558 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); |
542 | } | 559 | } |
543 | 560 | ||
544 | #ifdef X86_BTS | 561 | #ifdef CONFIG_X86_PTRACE_BTS |
545 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | 562 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) |
546 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); | 563 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); |
547 | 564 | ||
548 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) | 565 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) |
549 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); | 566 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); |
550 | #endif | 567 | #endif /* CONFIG_X86_PTRACE_BTS */ |
551 | } | 568 | } |
552 | 569 | ||
553 | /* | 570 | /* |