diff options
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r-- | arch/x86/kernel/process_64.c | 54 |
1 files changed, 13 insertions, 41 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index fbb321d53d34..416fb9282f4f 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <asm/ia32.h> | 53 | #include <asm/ia32.h> |
54 | #include <asm/idle.h> | 54 | #include <asm/idle.h> |
55 | #include <asm/syscalls.h> | 55 | #include <asm/syscalls.h> |
56 | #include <asm/ds.h> | ||
56 | 57 | ||
57 | asmlinkage extern void ret_from_fork(void); | 58 | asmlinkage extern void ret_from_fork(void); |
58 | 59 | ||
@@ -236,14 +237,8 @@ void exit_thread(void) | |||
236 | t->io_bitmap_max = 0; | 237 | t->io_bitmap_max = 0; |
237 | put_cpu(); | 238 | put_cpu(); |
238 | } | 239 | } |
239 | #ifdef CONFIG_X86_DS | 240 | |
240 | /* Free any DS contexts that have not been properly released. */ | 241 | ds_exit_thread(current); |
241 | if (unlikely(t->ds_ctx)) { | ||
242 | /* we clear debugctl to make sure DS is not used. */ | ||
243 | update_debugctlmsr(0); | ||
244 | ds_free(t->ds_ctx); | ||
245 | } | ||
246 | #endif /* CONFIG_X86_DS */ | ||
247 | } | 242 | } |
248 | 243 | ||
249 | void flush_thread(void) | 244 | void flush_thread(void) |
@@ -373,6 +368,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | |||
373 | if (err) | 368 | if (err) |
374 | goto out; | 369 | goto out; |
375 | } | 370 | } |
371 | |||
372 | ds_copy_thread(p, me); | ||
373 | |||
374 | clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR); | ||
375 | p->thread.debugctlmsr = 0; | ||
376 | |||
376 | err = 0; | 377 | err = 0; |
377 | out: | 378 | out: |
378 | if (err && p->thread.io_bitmap_ptr) { | 379 | if (err && p->thread.io_bitmap_ptr) { |
@@ -471,35 +472,14 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
471 | struct tss_struct *tss) | 472 | struct tss_struct *tss) |
472 | { | 473 | { |
473 | struct thread_struct *prev, *next; | 474 | struct thread_struct *prev, *next; |
474 | unsigned long debugctl; | ||
475 | 475 | ||
476 | prev = &prev_p->thread, | 476 | prev = &prev_p->thread, |
477 | next = &next_p->thread; | 477 | next = &next_p->thread; |
478 | 478 | ||
479 | debugctl = prev->debugctlmsr; | 479 | if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) || |
480 | 480 | test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR)) | |
481 | #ifdef CONFIG_X86_DS | 481 | ds_switch_to(prev_p, next_p); |
482 | { | 482 | else if (next->debugctlmsr != prev->debugctlmsr) |
483 | unsigned long ds_prev = 0, ds_next = 0; | ||
484 | |||
485 | if (prev->ds_ctx) | ||
486 | ds_prev = (unsigned long)prev->ds_ctx->ds; | ||
487 | if (next->ds_ctx) | ||
488 | ds_next = (unsigned long)next->ds_ctx->ds; | ||
489 | |||
490 | if (ds_next != ds_prev) { | ||
491 | /* | ||
492 | * We clear debugctl to make sure DS | ||
493 | * is not in use when we change it: | ||
494 | */ | ||
495 | debugctl = 0; | ||
496 | update_debugctlmsr(0); | ||
497 | wrmsrl(MSR_IA32_DS_AREA, ds_next); | ||
498 | } | ||
499 | } | ||
500 | #endif /* CONFIG_X86_DS */ | ||
501 | |||
502 | if (next->debugctlmsr != debugctl) | ||
503 | update_debugctlmsr(next->debugctlmsr); | 483 | update_debugctlmsr(next->debugctlmsr); |
504 | 484 | ||
505 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { | 485 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { |
@@ -534,14 +514,6 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
534 | */ | 514 | */ |
535 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); | 515 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); |
536 | } | 516 | } |
537 | |||
538 | #ifdef CONFIG_X86_PTRACE_BTS | ||
539 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | ||
540 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); | ||
541 | |||
542 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) | ||
543 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); | ||
544 | #endif /* CONFIG_X86_PTRACE_BTS */ | ||
545 | } | 517 | } |
546 | 518 | ||
547 | /* | 519 | /* |