aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r--arch/x86/kernel/process_64.c54
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
57asmlinkage extern void ret_from_fork(void); 58asmlinkage 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
249void flush_thread(void) 244void 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;
377out: 378out:
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/*