X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fx86_64%2Fkernel%2Fsmp.c;h=1e379ed17b1d7549a3bf48f8c772d4751e516baa;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=b183fafacd563b32a6f249a52d7ef45fea830d7c;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index b183fafac..1e379ed17 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -25,7 +25,9 @@ #include #include #include +#include #include +#include /* * 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 */ +}