aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_64.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
commita9de18eb761f7c1c860964b2e5addc1a35c7e861 (patch)
tree886e75fdfd09690cd262ca69cb7f5d1d42b48602 /arch/x86/kernel/process_64.c
parentb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (diff)
parent6a94cb73064c952255336cc57731904174b2c58f (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.c65
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
57asmlinkage extern void ret_from_fork(void); 59asmlinkage 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}
69EXPORT_SYMBOL_GPL(idle_notifier_register);
70
71void idle_notifier_unregister(struct notifier_block *n)
72{
73 atomic_notifier_chain_unregister(&idle_notifier, n);
74}
75EXPORT_SYMBOL_GPL(idle_notifier_unregister);
67 76
68void enter_idle(void) 77void 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
253void flush_thread(void) 256void 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;
381out: 390out:
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 */
560struct 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;