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