93 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef _ASM_X86_MMU_CONTEXT_H
 | |
| #define _ASM_X86_MMU_CONTEXT_H
 | |
| 
 | |
| #include <asm/desc.h>
 | |
| #include <asm/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 (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
 | |
| 		percpu_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)) {
 | |
| 		/* stop flush ipis for the previous mm */
 | |
| 		cpumask_clear_cpu(cpu, mm_cpumask(prev));
 | |
| #ifdef CONFIG_SMP
 | |
| 		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
 | |
| 		percpu_write(cpu_tlbstate.active_mm, next);
 | |
| #endif
 | |
| 		cpumask_set_cpu(cpu, mm_cpumask(next));
 | |
| 
 | |
| 		/* Re-load page tables */
 | |
| 		load_cr3(next->pgd);
 | |
| 
 | |
| 		/*
 | |
| 		 * 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 {
 | |
| 		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
 | |
| 		BUG_ON(percpu_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 */
 |