[PATCH] x86_64: Remove long obsolete CVS
[pandora-kernel.git] / arch / x86_64 / kernel / process.c
index 22a05de..52c03f6 100644 (file)
@@ -10,7 +10,6 @@
  *     Andi Kleen.
  *
  *     CPU hotplug support - ashok.raj@intel.com
- *  $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $
  */
 
 /*
@@ -35,8 +34,8 @@
 #include <linux/ptrace.h>
 #include <linux/utsname.h>
 #include <linux/random.h>
-#include <linux/kprobes.h>
 #include <linux/notifier.h>
+#include <linux/kprobes.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -66,24 +65,17 @@ EXPORT_SYMBOL(boot_option_idle_override);
 void (*pm_idle)(void);
 static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
 
-static struct notifier_block *idle_notifier;
-static DEFINE_SPINLOCK(idle_notifier_lock);
+static ATOMIC_NOTIFIER_HEAD(idle_notifier);
 
 void idle_notifier_register(struct notifier_block *n)
 {
-       unsigned long flags;
-       spin_lock_irqsave(&idle_notifier_lock, flags);
-       notifier_chain_register(&idle_notifier, n);
-       spin_unlock_irqrestore(&idle_notifier_lock, flags);
+       atomic_notifier_chain_register(&idle_notifier, n);
 }
 EXPORT_SYMBOL_GPL(idle_notifier_register);
 
 void idle_notifier_unregister(struct notifier_block *n)
 {
-       unsigned long flags;
-       spin_lock_irqsave(&idle_notifier_lock, flags);
-       notifier_chain_unregister(&idle_notifier, n);
-       spin_unlock_irqrestore(&idle_notifier_lock, flags);
+       atomic_notifier_chain_unregister(&idle_notifier, n);
 }
 EXPORT_SYMBOL(idle_notifier_unregister);
 
@@ -93,13 +85,13 @@ static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE;
 void enter_idle(void)
 {
        __get_cpu_var(idle_state) = CPU_IDLE;
-       notifier_call_chain(&idle_notifier, IDLE_START, NULL);
+       atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
 }
 
 static void __exit_idle(void)
 {
        __get_cpu_var(idle_state) = CPU_NOT_IDLE;
-       notifier_call_chain(&idle_notifier, IDLE_END, NULL);
+       atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
 }
 
 /* Called from interrupts to signify idle end */
@@ -114,7 +106,7 @@ void exit_idle(void)
  * We use this if we don't have any better
  * idle routine..
  */
-void default_idle(void)
+static void default_idle(void)
 {
        local_irq_enable();
 
@@ -353,13 +345,6 @@ void exit_thread(void)
        struct task_struct *me = current;
        struct thread_struct *t = &me->thread;
 
-       /*
-        * Remove function-return probe instances associated with this task
-        * and put them back on the free list. Do not insert an exit probe for
-        * this function, it will be disabled by kprobe_flush_task if you do.
-        */
-       kprobe_flush_task(me);
-
        if (me->thread.io_bitmap_ptr) { 
                struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
 
@@ -508,7 +493,7 @@ out:
 /*
  * This special macro can be used to load a debugging register
  */
-#define loaddebug(thread,r) set_debug(thread->debugreg ## r, r)
+#define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r)
 
 /*
  *     switch_to(x,y) should switch tasks from x to y.
@@ -527,8 +512,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        int cpu = smp_processor_id();  
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
 
-       unlazy_fpu(prev_p);
-
        /*
         * Reload esp0, LDT and the page table pointer:
         */
@@ -586,11 +569,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        }
 
        /* 
-        * Switch the PDA context.
+        * Switch the PDA and FPU contexts.
         */
        prev->userrsp = read_pda(oldrsp); 
        write_pda(oldrsp, next->userrsp); 
        write_pda(pcurrent, next_p); 
+
+       /* This must be here to ensure both math_state_restore() and
+          kernel_fpu_begin() work consistently. 
+          And the AMD workaround requires it to be after DS reload. */
+       unlazy_fpu(prev_p);
        write_pda(kernelstack,
                  task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
 
@@ -794,10 +782,16 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
        }
        case ARCH_GET_GS: { 
                unsigned long base;
+               unsigned gsindex;
                if (task->thread.gsindex == GS_TLS_SEL)
                        base = read_32bit_tls(task, GS_TLS);
-               else if (doit)
-                       rdmsrl(MSR_KERNEL_GS_BASE, base);
+               else if (doit) {
+                       asm("movl %%gs,%0" : "=r" (gsindex));
+                       if (gsindex)
+                               rdmsrl(MSR_KERNEL_GS_BASE, base);
+                       else
+                               base = task->thread.gs;
+               }
                else
                        base = task->thread.gs;
                ret = put_user(base, (unsigned long __user *)addr);