vserver 2.0 rc7
[linux-2.6.git] / arch / x86_64 / kernel / smp.c
index b183faf..1e379ed 100644 (file)
@@ -25,7 +25,9 @@
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/mach_apic.h>
+#include <asm/mmu_context.h>
 #include <asm/proto.h>
+#include <asm/apicdef.h>
 
 /*
  *     Smarter SMP flushing macros. 
@@ -41,7 +43,7 @@ static cpumask_t flush_cpumask;
 static struct mm_struct * flush_mm;
 static unsigned long flush_va;
 static DEFINE_SPINLOCK(tlbstate_lock);
-#define FLUSH_ALL      0xffffffff
+#define FLUSH_ALL      -1ULL
 
 /*
  * We cannot call mmdrop() because we are in interrupt context, 
@@ -52,7 +54,7 @@ static inline void leave_mm (unsigned long cpu)
        if (read_pda(mmu_state) == TLBSTATE_OK)
                BUG();
        clear_bit(cpu, &read_pda(active_mm)->cpu_vm_mask);
-       __flush_tlb();
+       load_cr3(swapper_pg_dir);
 }
 
 /*
@@ -372,7 +374,10 @@ void smp_send_stop(void)
        __smp_call_function(smp_really_stop_cpu, NULL, 0, 0);
        if (!nolock)
                spin_unlock(&call_lock);
-       smp_stop_cpu();
+
+       local_irq_disable();
+       disable_local_APIC();
+       local_irq_enable();
 }
 
 /*
@@ -409,3 +414,27 @@ asmlinkage void smp_call_function_interrupt(void)
                atomic_inc(&call_data->finished);
        }
 }
+
+int safe_smp_processor_id(void)
+{
+       int apicid, i;
+
+       if (disable_apic)
+               return 0;
+
+       apicid = hard_smp_processor_id();
+       if (x86_cpu_to_apicid[apicid] == apicid)
+               return apicid;
+
+       for (i = 0; i < NR_CPUS; ++i) {
+               if (x86_cpu_to_apicid[i] == apicid)
+                       return i;
+       }
+
+       /* No entries in x86_cpu_to_apicid?  Either no MPS|ACPI,
+        * or called too early.  Either way, we must be CPU 0. */
+       if (x86_cpu_to_apicid[0] == BAD_APICID)
+               return 0;
+
+       return 0; /* Should not happen */
+}