|  | #ifndef _ASM_X86_MMU_CONTEXT_H | 
|  | #define _ASM_X86_MMU_CONTEXT_H | 
|  |  | 
|  | #include <asm/desc.h> | 
|  | #include <linux/atomic.h> | 
|  | #include <asm/pgalloc.h> | 
|  | #include <asm/tlbflush.h> | 
|  | #include <asm/paravirt.h> | 
|  | #ifndef CONFIG_PARAVIRT | 
|  | #include <asm-generic/mm_hooks.h> | 
|  |  | 
|  | static inline void paravirt_activate_mm(struct mm_struct *prev, | 
|  | struct mm_struct *next) | 
|  | { | 
|  | } | 
|  | #endif	/* !CONFIG_PARAVIRT */ | 
|  |  | 
|  | /* | 
|  | * Used for LDT copy/destruction. | 
|  | */ | 
|  | int init_new_context(struct task_struct *tsk, struct mm_struct *mm); | 
|  | void destroy_context(struct mm_struct *mm); | 
|  |  | 
|  |  | 
|  | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | 
|  | { | 
|  | #ifdef CONFIG_SMP | 
|  | if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) | 
|  | this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | 
|  | struct task_struct *tsk) | 
|  | { | 
|  | unsigned cpu = smp_processor_id(); | 
|  |  | 
|  | if (likely(prev != next)) { | 
|  | #ifdef CONFIG_SMP | 
|  | this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK); | 
|  | this_cpu_write(cpu_tlbstate.active_mm, next); | 
|  | #endif | 
|  | cpumask_set_cpu(cpu, mm_cpumask(next)); | 
|  |  | 
|  | /* Re-load page tables */ | 
|  | load_cr3(next->pgd); | 
|  |  | 
|  | /* stop flush ipis for the previous mm */ | 
|  | cpumask_clear_cpu(cpu, mm_cpumask(prev)); | 
|  |  | 
|  | /* | 
|  | * load the LDT, if the LDT is different: | 
|  | */ | 
|  | if (unlikely(prev->context.ldt != next->context.ldt)) | 
|  | load_LDT_nolock(&next->context); | 
|  | } | 
|  | #ifdef CONFIG_SMP | 
|  | else { | 
|  | this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK); | 
|  | BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next); | 
|  |  | 
|  | if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next))) { | 
|  | /* We were in lazy tlb mode and leave_mm disabled | 
|  | * tlb flush IPI delivery. We must reload CR3 | 
|  | * to make sure to use no freed page tables. | 
|  | */ | 
|  | load_cr3(next->pgd); | 
|  | load_LDT_nolock(&next->context); | 
|  | } | 
|  | } | 
|  | #endif | 
|  | } | 
|  |  | 
|  | #define activate_mm(prev, next)			\ | 
|  | do {						\ | 
|  | paravirt_activate_mm((prev), (next));	\ | 
|  | switch_mm((prev), (next), NULL);	\ | 
|  | } while (0); | 
|  |  | 
|  | #ifdef CONFIG_X86_32 | 
|  | #define deactivate_mm(tsk, mm)			\ | 
|  | do {						\ | 
|  | lazy_load_gs(0);			\ | 
|  | } while (0) | 
|  | #else | 
|  | #define deactivate_mm(tsk, mm)			\ | 
|  | do {						\ | 
|  | load_gs_index(0);			\ | 
|  | loadsegment(fs, 0);			\ | 
|  | } while (0) | 
|  | #endif | 
|  |  | 
|  | #endif /* _ASM_X86_MMU_CONTEXT_H */ |