xref: /openbmc/linux/arch/x86/include/asm/mmu_context.h (revision ccbeed3a)
11965aae3SH. Peter Anvin #ifndef _ASM_X86_MMU_CONTEXT_H
21965aae3SH. Peter Anvin #define _ASM_X86_MMU_CONTEXT_H
3bb898558SAl Viro 
4bb898558SAl Viro #include <asm/desc.h>
5bb898558SAl Viro #include <asm/atomic.h>
6bb898558SAl Viro #include <asm/pgalloc.h>
7bb898558SAl Viro #include <asm/tlbflush.h>
8bb898558SAl Viro #include <asm/paravirt.h>
9bb898558SAl Viro #ifndef CONFIG_PARAVIRT
10bb898558SAl Viro #include <asm-generic/mm_hooks.h>
11bb898558SAl Viro 
12bb898558SAl Viro static inline void paravirt_activate_mm(struct mm_struct *prev,
13bb898558SAl Viro 					struct mm_struct *next)
14bb898558SAl Viro {
15bb898558SAl Viro }
16bb898558SAl Viro #endif	/* !CONFIG_PARAVIRT */
17bb898558SAl Viro 
18bb898558SAl Viro /*
19bb898558SAl Viro  * Used for LDT copy/destruction.
20bb898558SAl Viro  */
21bb898558SAl Viro int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
22bb898558SAl Viro void destroy_context(struct mm_struct *mm);
23bb898558SAl Viro 
246826c8ffSBrian Gerst 
256826c8ffSBrian Gerst static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
266826c8ffSBrian Gerst {
276826c8ffSBrian Gerst #ifdef CONFIG_SMP
286826c8ffSBrian Gerst 	if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
296826c8ffSBrian Gerst 		percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
30bb898558SAl Viro #endif
316826c8ffSBrian Gerst }
326826c8ffSBrian Gerst 
336826c8ffSBrian Gerst static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
346826c8ffSBrian Gerst 			     struct task_struct *tsk)
356826c8ffSBrian Gerst {
366826c8ffSBrian Gerst 	unsigned cpu = smp_processor_id();
376826c8ffSBrian Gerst 
386826c8ffSBrian Gerst 	if (likely(prev != next)) {
396826c8ffSBrian Gerst 		/* stop flush ipis for the previous mm */
406826c8ffSBrian Gerst 		cpu_clear(cpu, prev->cpu_vm_mask);
416826c8ffSBrian Gerst #ifdef CONFIG_SMP
426826c8ffSBrian Gerst 		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
436826c8ffSBrian Gerst 		percpu_write(cpu_tlbstate.active_mm, next);
446826c8ffSBrian Gerst #endif
456826c8ffSBrian Gerst 		cpu_set(cpu, next->cpu_vm_mask);
466826c8ffSBrian Gerst 
476826c8ffSBrian Gerst 		/* Re-load page tables */
486826c8ffSBrian Gerst 		load_cr3(next->pgd);
496826c8ffSBrian Gerst 
506826c8ffSBrian Gerst 		/*
516826c8ffSBrian Gerst 		 * load the LDT, if the LDT is different:
526826c8ffSBrian Gerst 		 */
536826c8ffSBrian Gerst 		if (unlikely(prev->context.ldt != next->context.ldt))
546826c8ffSBrian Gerst 			load_LDT_nolock(&next->context);
556826c8ffSBrian Gerst 	}
566826c8ffSBrian Gerst #ifdef CONFIG_SMP
576826c8ffSBrian Gerst 	else {
586826c8ffSBrian Gerst 		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
596826c8ffSBrian Gerst 		BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next);
606826c8ffSBrian Gerst 
616826c8ffSBrian Gerst 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
626826c8ffSBrian Gerst 			/* We were in lazy tlb mode and leave_mm disabled
636826c8ffSBrian Gerst 			 * tlb flush IPI delivery. We must reload CR3
646826c8ffSBrian Gerst 			 * to make sure to use no freed page tables.
656826c8ffSBrian Gerst 			 */
666826c8ffSBrian Gerst 			load_cr3(next->pgd);
676826c8ffSBrian Gerst 			load_LDT_nolock(&next->context);
686826c8ffSBrian Gerst 		}
696826c8ffSBrian Gerst 	}
706826c8ffSBrian Gerst #endif
716826c8ffSBrian Gerst }
72bb898558SAl Viro 
73bb898558SAl Viro #define activate_mm(prev, next)			\
74bb898558SAl Viro do {						\
75bb898558SAl Viro 	paravirt_activate_mm((prev), (next));	\
76bb898558SAl Viro 	switch_mm((prev), (next), NULL);	\
77bb898558SAl Viro } while (0);
78bb898558SAl Viro 
796826c8ffSBrian Gerst #ifdef CONFIG_X86_32
806826c8ffSBrian Gerst #define deactivate_mm(tsk, mm)			\
816826c8ffSBrian Gerst do {						\
82ccbeed3aSTejun Heo 	lazy_load_gs(0);			\
836826c8ffSBrian Gerst } while (0)
846826c8ffSBrian Gerst #else
856826c8ffSBrian Gerst #define deactivate_mm(tsk, mm)			\
866826c8ffSBrian Gerst do {						\
876826c8ffSBrian Gerst 	load_gs_index(0);			\
886826c8ffSBrian Gerst 	loadsegment(fs, 0);			\
896826c8ffSBrian Gerst } while (0)
906826c8ffSBrian Gerst #endif
91bb898558SAl Viro 
921965aae3SH. Peter Anvin #endif /* _ASM_X86_MMU_CONTEXT_H */
93