#define ASID_FIRST_VERSION (1 << ASID_BITS)
extern unsigned int cpu_last_asid;
+#ifdef CONFIG_SMP
+DECLARE_PER_CPU(struct mm_struct *, current_mm);
+#endif
void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
void __new_context(struct mm_struct *mm);
static inline void check_context(struct mm_struct *mm)
{
+ /*
+ * This code is executed with interrupts enabled. Therefore,
+ * mm->context.id cannot be updated to the latest ASID version
+ * on a different CPU (and condition below not triggered)
+ * without first getting an IPI to reset the context. The
+ * alternative is to take a read_lock on mm->context.id_lock
+ * (after changing its type to rwlock_t).
+ */
if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS))
__new_context(mm);
__flush_icache_all();
#endif
if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
+#ifdef CONFIG_SMP
+ struct mm_struct **crt_mm = &per_cpu(current_mm, cpu);
+ *crt_mm = next;
+#endif
check_context(next);
cpu_switch_mm(next->pgd, next);
if (cache_is_vivt())