diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-31 02:31:57 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-31 02:31:57 -0500 |
commit | a9de18eb761f7c1c860964b2e5addc1a35c7e861 (patch) | |
tree | 886e75fdfd09690cd262ca69cb7f5d1d42b48602 /arch/x86/kernel/process_64.c | |
parent | b2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (diff) | |
parent | 6a94cb73064c952255336cc57731904174b2c58f (diff) |
Merge branch 'linus' into stackprotector
Conflicts:
arch/x86/include/asm/pda.h
kernel/fork.c
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r-- | arch/x86/kernel/process_64.c | 65 |
1 files changed, 23 insertions, 42 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 749d5f888d4d..efb0396e19bf 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/prctl.h> | 40 | #include <linux/prctl.h> |
41 | #include <linux/uaccess.h> | 41 | #include <linux/uaccess.h> |
42 | #include <linux/io.h> | 42 | #include <linux/io.h> |
43 | #include <linux/ftrace.h> | ||
43 | 44 | ||
44 | #include <asm/pgtable.h> | 45 | #include <asm/pgtable.h> |
45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
@@ -53,6 +54,7 @@ | |||
53 | #include <asm/ia32.h> | 54 | #include <asm/ia32.h> |
54 | #include <asm/idle.h> | 55 | #include <asm/idle.h> |
55 | #include <asm/syscalls.h> | 56 | #include <asm/syscalls.h> |
57 | #include <asm/ds.h> | ||
56 | 58 | ||
57 | asmlinkage extern void ret_from_fork(void); | 59 | asmlinkage extern void ret_from_fork(void); |
58 | 60 | ||
@@ -64,6 +66,13 @@ void idle_notifier_register(struct notifier_block *n) | |||
64 | { | 66 | { |
65 | atomic_notifier_chain_register(&idle_notifier, n); | 67 | atomic_notifier_chain_register(&idle_notifier, n); |
66 | } | 68 | } |
69 | EXPORT_SYMBOL_GPL(idle_notifier_register); | ||
70 | |||
71 | void idle_notifier_unregister(struct notifier_block *n) | ||
72 | { | ||
73 | atomic_notifier_chain_unregister(&idle_notifier, n); | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(idle_notifier_unregister); | ||
67 | 76 | ||
68 | void enter_idle(void) | 77 | void enter_idle(void) |
69 | { | 78 | { |
@@ -240,14 +249,8 @@ void exit_thread(void) | |||
240 | t->io_bitmap_max = 0; | 249 | t->io_bitmap_max = 0; |
241 | put_cpu(); | 250 | put_cpu(); |
242 | } | 251 | } |
243 | #ifdef CONFIG_X86_DS | 252 | |
244 | /* Free any DS contexts that have not been properly released. */ | 253 | ds_exit_thread(current); |
245 | if (unlikely(t->ds_ctx)) { | ||
246 | /* we clear debugctl to make sure DS is not used. */ | ||
247 | update_debugctlmsr(0); | ||
248 | ds_free(t->ds_ctx); | ||
249 | } | ||
250 | #endif /* CONFIG_X86_DS */ | ||
251 | } | 254 | } |
252 | 255 | ||
253 | void flush_thread(void) | 256 | void flush_thread(void) |
@@ -377,6 +380,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | |||
377 | if (err) | 380 | if (err) |
378 | goto out; | 381 | goto out; |
379 | } | 382 | } |
383 | |||
384 | ds_copy_thread(p, me); | ||
385 | |||
386 | clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR); | ||
387 | p->thread.debugctlmsr = 0; | ||
388 | |||
380 | err = 0; | 389 | err = 0; |
381 | out: | 390 | out: |
382 | if (err && p->thread.io_bitmap_ptr) { | 391 | if (err && p->thread.io_bitmap_ptr) { |
@@ -475,35 +484,14 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
475 | struct tss_struct *tss) | 484 | struct tss_struct *tss) |
476 | { | 485 | { |
477 | struct thread_struct *prev, *next; | 486 | struct thread_struct *prev, *next; |
478 | unsigned long debugctl; | ||
479 | 487 | ||
480 | prev = &prev_p->thread, | 488 | prev = &prev_p->thread, |
481 | next = &next_p->thread; | 489 | next = &next_p->thread; |
482 | 490 | ||
483 | debugctl = prev->debugctlmsr; | 491 | if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) || |
484 | 492 | test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR)) | |
485 | #ifdef CONFIG_X86_DS | 493 | ds_switch_to(prev_p, next_p); |
486 | { | 494 | else if (next->debugctlmsr != prev->debugctlmsr) |
487 | unsigned long ds_prev = 0, ds_next = 0; | ||
488 | |||
489 | if (prev->ds_ctx) | ||
490 | ds_prev = (unsigned long)prev->ds_ctx->ds; | ||
491 | if (next->ds_ctx) | ||
492 | ds_next = (unsigned long)next->ds_ctx->ds; | ||
493 | |||
494 | if (ds_next != ds_prev) { | ||
495 | /* | ||
496 | * We clear debugctl to make sure DS | ||
497 | * is not in use when we change it: | ||
498 | */ | ||
499 | debugctl = 0; | ||
500 | update_debugctlmsr(0); | ||
501 | wrmsrl(MSR_IA32_DS_AREA, ds_next); | ||
502 | } | ||
503 | } | ||
504 | #endif /* CONFIG_X86_DS */ | ||
505 | |||
506 | if (next->debugctlmsr != debugctl) | ||
507 | update_debugctlmsr(next->debugctlmsr); | 495 | update_debugctlmsr(next->debugctlmsr); |
508 | 496 | ||
509 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { | 497 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { |
@@ -538,14 +526,6 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
538 | */ | 526 | */ |
539 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); | 527 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); |
540 | } | 528 | } |
541 | |||
542 | #ifdef CONFIG_X86_PTRACE_BTS | ||
543 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | ||
544 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); | ||
545 | |||
546 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) | ||
547 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); | ||
548 | #endif /* CONFIG_X86_PTRACE_BTS */ | ||
549 | } | 529 | } |
550 | 530 | ||
551 | /* | 531 | /* |
@@ -556,8 +536,9 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
556 | * - could test fs/gs bitsliced | 536 | * - could test fs/gs bitsliced |
557 | * | 537 | * |
558 | * Kprobes not supported here. Set the probe on schedule instead. | 538 | * Kprobes not supported here. Set the probe on schedule instead. |
539 | * Function graph tracer not supported too. | ||
559 | */ | 540 | */ |
560 | struct task_struct * | 541 | __notrace_funcgraph struct task_struct * |
561 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | 542 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) |
562 | { | 543 | { |
563 | struct thread_struct *prev = &prev_p->thread; | 544 | struct thread_struct *prev = &prev_p->thread; |