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 { \ 82*ccbeed3aSTejun 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