1 #ifndef _ASM_X86_MMU_CONTEXT_H
2 #define _ASM_X86_MMU_CONTEXT_H
5 #include <linux/atomic.h>
6 #include <asm/pgalloc.h>
7 #include <asm/tlbflush.h>
8 #include <asm/paravirt.h>
9 #ifndef CONFIG_PARAVIRT
10 #include <asm-generic/mm_hooks.h>
12 static inline void paravirt_activate_mm(struct mm_struct *prev,
13 struct mm_struct *next)
16 #endif /* !CONFIG_PARAVIRT */
19 * ldt_structs can be allocated, used, and freed, but they are never
20 * modified while live.
24 * Xen requires page-aligned LDTs with special permissions. This is
25 * needed to prevent us from installing evil descriptors such as
26 * call gates. On native, we could merge the ldt_struct and LDT
27 * allocations, but it's not worth trying to optimize.
29 struct desc_struct *entries;
33 static inline void load_mm_ldt(struct mm_struct *mm)
35 struct ldt_struct *ldt;
37 /* smp_read_barrier_depends synchronizes with barrier in install_ldt */
38 ldt = ACCESS_ONCE(mm->context.ldt);
39 smp_read_barrier_depends();
42 * Any change to mm->context.ldt is followed by an IPI to all
43 * CPUs with the mm active. The LDT will not be freed until
44 * after the IPI is handled by all such CPUs. This means that,
45 * if the ldt_struct changes before we return, the values we see
46 * will be safe, and the new values will be loaded before we run
49 * NB: don't try to convert this to use RCU without extreme care.
50 * We would still need IRQs off, because we don't want to change
51 * the local LDT after an IPI loaded a newer value than the one
56 set_ldt(ldt->entries, ldt->size);
60 DEBUG_LOCKS_WARN_ON(preemptible());
64 * Used for LDT copy/destruction.
66 int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
67 void destroy_context(struct mm_struct *mm);
70 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
72 if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
73 percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
76 extern void switch_mm(struct mm_struct *prev, struct mm_struct *next,
77 struct task_struct *tsk);
79 extern void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
80 struct task_struct *tsk);
81 #define switch_mm_irqs_off switch_mm_irqs_off
83 #define activate_mm(prev, next) \
85 paravirt_activate_mm((prev), (next)); \
86 switch_mm((prev), (next), NULL); \
90 #define deactivate_mm(tsk, mm) \
95 #define deactivate_mm(tsk, mm) \
102 #endif /* _ASM_X86_MMU_CONTEXT_H */