2008-10-23 09:26:29 +04:00
# ifndef _ASM_X86_MMU_CONTEXT_H
# define _ASM_X86_MMU_CONTEXT_H
2008-06-25 08:19:07 +04:00
# include <asm/desc.h>
# include <asm/atomic.h>
# include <asm/pgalloc.h>
# include <asm/tlbflush.h>
# include <asm/paravirt.h>
# ifndef CONFIG_PARAVIRT
# include <asm-generic/mm_hooks.h>
static inline void paravirt_activate_mm ( struct mm_struct * prev ,
struct mm_struct * next )
{
}
# endif /* !CONFIG_PARAVIRT */
/*
* Used for LDT copy / destruction .
*/
int init_new_context ( struct task_struct * tsk , struct mm_struct * mm ) ;
void destroy_context ( struct mm_struct * mm ) ;
2009-01-21 11:26:06 +03:00
static inline void enter_lazy_tlb ( struct mm_struct * mm , struct task_struct * tsk )
{
# ifdef CONFIG_SMP
if ( percpu_read ( cpu_tlbstate . state ) = = TLBSTATE_OK )
percpu_write ( cpu_tlbstate . state , TLBSTATE_LAZY ) ;
# endif
}
static inline void switch_mm ( struct mm_struct * prev , struct mm_struct * next ,
struct task_struct * tsk )
{
unsigned cpu = smp_processor_id ( ) ;
if ( likely ( prev ! = next ) ) {
# ifdef CONFIG_SMP
percpu_write ( cpu_tlbstate . state , TLBSTATE_OK ) ;
percpu_write ( cpu_tlbstate . active_mm , next ) ;
2007-10-11 13:20:03 +04:00
# endif
2009-09-24 19:34:51 +04:00
cpumask_set_cpu ( cpu , mm_cpumask ( next ) ) ;
2009-01-21 11:26:06 +03:00
/* Re-load page tables */
load_cr3 ( next - > pgd ) ;
2011-02-03 23:20:04 +03:00
/* stop flush ipis for the previous mm */
cpumask_clear_cpu ( cpu , mm_cpumask ( prev ) ) ;
2009-01-21 11:26:06 +03:00
/*
* load the LDT , if the LDT is different :
*/
if ( unlikely ( prev - > context . ldt ! = next - > context . ldt ) )
load_LDT_nolock ( & next - > context ) ;
}
# ifdef CONFIG_SMP
else {
percpu_write ( cpu_tlbstate . state , TLBSTATE_OK ) ;
BUG_ON ( percpu_read ( cpu_tlbstate . active_mm ) ! = next ) ;
2009-09-24 19:34:51 +04:00
if ( ! cpumask_test_and_set_cpu ( cpu , mm_cpumask ( next ) ) ) {
2009-01-21 11:26:06 +03:00
/* We were in lazy tlb mode and leave_mm disabled
* tlb flush IPI delivery . We must reload CR3
* to make sure to use no freed page tables .
*/
load_cr3 ( next - > pgd ) ;
load_LDT_nolock ( & next - > context ) ;
}
}
# endif
}
2008-06-25 08:19:07 +04:00
# define activate_mm(prev, next) \
do { \
paravirt_activate_mm ( ( prev ) , ( next ) ) ; \
switch_mm ( ( prev ) , ( next ) , NULL ) ; \
} while ( 0 ) ;
2009-01-21 11:26:06 +03:00
# ifdef CONFIG_X86_32
# define deactivate_mm(tsk, mm) \
do { \
2009-02-09 16:17:40 +03:00
lazy_load_gs ( 0 ) ; \
2009-01-21 11:26:06 +03:00
} while ( 0 )
# else
# define deactivate_mm(tsk, mm) \
do { \
load_gs_index ( 0 ) ; \
loadsegment ( fs , 0 ) ; \
} while ( 0 )
# endif
2008-06-25 08:19:07 +04:00
2008-10-23 09:26:29 +04:00
# endif /* _ASM_X86_MMU_CONTEXT_H */