]> err.no Git - linux-2.6/blobdiff - arch/x86/kernel/process_64.c
Merge branch 'core/stacktrace' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
[linux-2.6] / arch / x86 / kernel / process_64.c
index 488eaca47bd8c7a2842be634edbdfc423c13b9aa..a8e53626ac9aaf5fc8290908aaf42552556a1b11 100644 (file)
@@ -134,7 +134,10 @@ void cpu_idle(void)
                         */
                        local_irq_disable();
                        enter_idle();
+                       /* Don't trace irqs off for idle */
+                       stop_critical_timings();
                        pm_idle();
+                       start_critical_timings();
                        /* In many cases the interrupt that ended idle
                           has already called exit_idle. But some idle
                           loops can be woken up without interrupt. */
@@ -538,6 +541,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                                 *next = &next_p->thread;
        int cpu = smp_processor_id();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
+       unsigned fsindex, gsindex;
 
        /* we're going to use this soon, after a few expensive things */
        if (next_p->fpu_counter>5)
@@ -560,6 +564,15 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        if (unlikely(next->ds | prev->ds))
                loadsegment(ds, next->ds);
 
+
+       /* We must save %fs and %gs before load_TLS() because
+        * %fs and %gs may be cleared by load_TLS().
+        *
+        * (e.g. xen_load_tls())
+        */
+       savesegment(fs, fsindex);
+       savesegment(gs, gsindex);
+
        load_TLS(next, cpu);
 
        /*
@@ -575,8 +588,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
         * Switch FS and GS.
         */
        { 
-               unsigned fsindex;
-               savesegment(fs, fsindex);
                /* segment register != 0 always requires a reload. 
                   also reload when it has changed. 
                   when prev process used 64bit base always reload
@@ -594,10 +605,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                if (next->fs) 
                        wrmsrl(MSR_FS_BASE, next->fs); 
                prev->fsindex = fsindex;
-       }
-       { 
-               unsigned gsindex;
-               savesegment(gs, gsindex);
+
                if (unlikely(gsindex | next->gsindex | prev->gs)) {
                        load_gs_index(next->gsindex);
                        if (gsindex)