11965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#ifndef _ASM_X86_MMU_CONTEXT_H 21965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#define _ASM_X86_MMU_CONTEXT_H 3c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge 4c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge#include <asm/desc.h> 560063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h> 6c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge#include <asm/pgalloc.h> 7c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge#include <asm/tlbflush.h> 8c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge#include <asm/paravirt.h> 9c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge#ifndef CONFIG_PARAVIRT 10c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge#include <asm-generic/mm_hooks.h> 11c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge 12c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardingestatic inline void paravirt_activate_mm(struct mm_struct *prev, 13c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge struct mm_struct *next) 14c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge{ 15c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge} 16c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge#endif /* !CONFIG_PARAVIRT */ 17c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge 18c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge/* 19c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge * Used for LDT copy/destruction. 20c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge */ 21c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardingeint init_new_context(struct task_struct *tsk, struct mm_struct *mm); 22c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardingevoid destroy_context(struct mm_struct *mm); 23c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge 246826c8ff07b5f95df0473a748a9831707079b940Brian Gerst 256826c8ff07b5f95df0473a748a9831707079b940Brian Gerststatic inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) 266826c8ff07b5f95df0473a748a9831707079b940Brian Gerst{ 276826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#ifdef CONFIG_SMP 286826c8ff07b5f95df0473a748a9831707079b940Brian Gerst if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) 296826c8ff07b5f95df0473a748a9831707079b940Brian Gerst percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); 306826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#endif 316826c8ff07b5f95df0473a748a9831707079b940Brian Gerst} 326826c8ff07b5f95df0473a748a9831707079b940Brian Gerst 336826c8ff07b5f95df0473a748a9831707079b940Brian Gerststatic inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 346826c8ff07b5f95df0473a748a9831707079b940Brian Gerst struct task_struct *tsk) 356826c8ff07b5f95df0473a748a9831707079b940Brian Gerst{ 366826c8ff07b5f95df0473a748a9831707079b940Brian Gerst unsigned cpu = smp_processor_id(); 376826c8ff07b5f95df0473a748a9831707079b940Brian Gerst 386826c8ff07b5f95df0473a748a9831707079b940Brian Gerst if (likely(prev != next)) { 396826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#ifdef CONFIG_SMP 406826c8ff07b5f95df0473a748a9831707079b940Brian Gerst percpu_write(cpu_tlbstate.state, TLBSTATE_OK); 416826c8ff07b5f95df0473a748a9831707079b940Brian Gerst percpu_write(cpu_tlbstate.active_mm, next); 4296a388de5dc53a8b234b3fd41f3ae2cedc9ffd42Thomas Gleixner#endif 4378f1c4d6b027993763a5aba83873b0462d06db8fRusty Russell cpumask_set_cpu(cpu, mm_cpumask(next)); 446826c8ff07b5f95df0473a748a9831707079b940Brian Gerst 456826c8ff07b5f95df0473a748a9831707079b940Brian Gerst /* Re-load page tables */ 466826c8ff07b5f95df0473a748a9831707079b940Brian Gerst load_cr3(next->pgd); 476826c8ff07b5f95df0473a748a9831707079b940Brian Gerst 48831d52bc153971b70e64eccfbed2b232394f22f8Suresh Siddha /* stop flush ipis for the previous mm */ 49831d52bc153971b70e64eccfbed2b232394f22f8Suresh Siddha cpumask_clear_cpu(cpu, mm_cpumask(prev)); 50831d52bc153971b70e64eccfbed2b232394f22f8Suresh Siddha 516826c8ff07b5f95df0473a748a9831707079b940Brian Gerst /* 526826c8ff07b5f95df0473a748a9831707079b940Brian Gerst * load the LDT, if the LDT is different: 536826c8ff07b5f95df0473a748a9831707079b940Brian Gerst */ 546826c8ff07b5f95df0473a748a9831707079b940Brian Gerst if (unlikely(prev->context.ldt != next->context.ldt)) 556826c8ff07b5f95df0473a748a9831707079b940Brian Gerst load_LDT_nolock(&next->context); 566826c8ff07b5f95df0473a748a9831707079b940Brian Gerst } 576826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#ifdef CONFIG_SMP 586826c8ff07b5f95df0473a748a9831707079b940Brian Gerst else { 596826c8ff07b5f95df0473a748a9831707079b940Brian Gerst percpu_write(cpu_tlbstate.state, TLBSTATE_OK); 606826c8ff07b5f95df0473a748a9831707079b940Brian Gerst BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); 616826c8ff07b5f95df0473a748a9831707079b940Brian Gerst 6278f1c4d6b027993763a5aba83873b0462d06db8fRusty Russell if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next))) { 636826c8ff07b5f95df0473a748a9831707079b940Brian Gerst /* We were in lazy tlb mode and leave_mm disabled 646826c8ff07b5f95df0473a748a9831707079b940Brian Gerst * tlb flush IPI delivery. We must reload CR3 656826c8ff07b5f95df0473a748a9831707079b940Brian Gerst * to make sure to use no freed page tables. 666826c8ff07b5f95df0473a748a9831707079b940Brian Gerst */ 676826c8ff07b5f95df0473a748a9831707079b940Brian Gerst load_cr3(next->pgd); 686826c8ff07b5f95df0473a748a9831707079b940Brian Gerst load_LDT_nolock(&next->context); 696826c8ff07b5f95df0473a748a9831707079b940Brian Gerst } 706826c8ff07b5f95df0473a748a9831707079b940Brian Gerst } 716826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#endif 726826c8ff07b5f95df0473a748a9831707079b940Brian Gerst} 73c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge 74c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge#define activate_mm(prev, next) \ 75c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardingedo { \ 76c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge paravirt_activate_mm((prev), (next)); \ 77c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge switch_mm((prev), (next), NULL); \ 78c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge} while (0); 79c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge 806826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#ifdef CONFIG_X86_32 816826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#define deactivate_mm(tsk, mm) \ 826826c8ff07b5f95df0473a748a9831707079b940Brian Gerstdo { \ 83ccbeed3a05908d201b47b6c3dd1a373138bba566Tejun Heo lazy_load_gs(0); \ 846826c8ff07b5f95df0473a748a9831707079b940Brian Gerst} while (0) 856826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#else 866826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#define deactivate_mm(tsk, mm) \ 876826c8ff07b5f95df0473a748a9831707079b940Brian Gerstdo { \ 886826c8ff07b5f95df0473a748a9831707079b940Brian Gerst load_gs_index(0); \ 896826c8ff07b5f95df0473a748a9831707079b940Brian Gerst loadsegment(fs, 0); \ 906826c8ff07b5f95df0473a748a9831707079b940Brian Gerst} while (0) 916826c8ff07b5f95df0473a748a9831707079b940Brian Gerst#endif 92c3c2fee38462fa34b90e0a5427c7fc564bb5c96cJeremy Fitzhardinge 931965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#endif /* _ASM_X86_MMU_CONTEXT_H */ 94