Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.13 149 lines 3.8 kB view raw
1#ifndef _I386_TLBFLUSH_H 2#define _I386_TLBFLUSH_H 3 4#include <linux/config.h> 5#include <linux/mm.h> 6#include <asm/processor.h> 7 8#define __flush_tlb() \ 9 do { \ 10 unsigned int tmpreg; \ 11 \ 12 __asm__ __volatile__( \ 13 "movl %%cr3, %0; \n" \ 14 "movl %0, %%cr3; # flush TLB \n" \ 15 : "=r" (tmpreg) \ 16 :: "memory"); \ 17 } while (0) 18 19/* 20 * Global pages have to be flushed a bit differently. Not a real 21 * performance problem because this does not happen often. 22 */ 23#define __flush_tlb_global() \ 24 do { \ 25 unsigned int tmpreg, cr4, cr4_orig; \ 26 \ 27 __asm__ __volatile__( \ 28 "movl %%cr4, %2; # turn off PGE \n" \ 29 "movl %2, %1; \n" \ 30 "andl %3, %1; \n" \ 31 "movl %1, %%cr4; \n" \ 32 "movl %%cr3, %0; \n" \ 33 "movl %0, %%cr3; # flush TLB \n" \ 34 "movl %2, %%cr4; # turn PGE back on \n" \ 35 : "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig) \ 36 : "i" (~X86_CR4_PGE) \ 37 : "memory"); \ 38 } while (0) 39 40extern unsigned long pgkern_mask; 41 42# define __flush_tlb_all() \ 43 do { \ 44 if (cpu_has_pge) \ 45 __flush_tlb_global(); \ 46 else \ 47 __flush_tlb(); \ 48 } while (0) 49 50#define cpu_has_invlpg (boot_cpu_data.x86 > 3) 51 52#define __flush_tlb_single(addr) \ 53 __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr)) 54 55#ifdef CONFIG_X86_INVLPG 56# define __flush_tlb_one(addr) __flush_tlb_single(addr) 57#else 58# define __flush_tlb_one(addr) \ 59 do { \ 60 if (cpu_has_invlpg) \ 61 __flush_tlb_single(addr); \ 62 else \ 63 __flush_tlb(); \ 64 } while (0) 65#endif 66 67/* 68 * TLB flushing: 69 * 70 * - flush_tlb() flushes the current mm struct TLBs 71 * - flush_tlb_all() flushes all processes TLBs 72 * - flush_tlb_mm(mm) flushes the specified mm context TLB's 73 * - flush_tlb_page(vma, vmaddr) flushes one page 74 * - flush_tlb_range(vma, start, end) flushes a range of pages 75 * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages 76 * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables 77 * 78 * ..but the i386 has somewhat limited tlb flushing capabilities, 79 * and page-granular flushes are available only on i486 and up. 80 */ 81 82#ifndef CONFIG_SMP 83 84#define flush_tlb() __flush_tlb() 85#define flush_tlb_all() __flush_tlb_all() 86#define local_flush_tlb() __flush_tlb() 87 88static inline void flush_tlb_mm(struct mm_struct *mm) 89{ 90 if (mm == current->active_mm) 91 __flush_tlb(); 92} 93 94static inline void flush_tlb_page(struct vm_area_struct *vma, 95 unsigned long addr) 96{ 97 if (vma->vm_mm == current->active_mm) 98 __flush_tlb_one(addr); 99} 100 101static inline void flush_tlb_range(struct vm_area_struct *vma, 102 unsigned long start, unsigned long end) 103{ 104 if (vma->vm_mm == current->active_mm) 105 __flush_tlb(); 106} 107 108#else 109 110#include <asm/smp.h> 111 112#define local_flush_tlb() \ 113 __flush_tlb() 114 115extern void flush_tlb_all(void); 116extern void flush_tlb_current_task(void); 117extern void flush_tlb_mm(struct mm_struct *); 118extern void flush_tlb_page(struct vm_area_struct *, unsigned long); 119 120#define flush_tlb() flush_tlb_current_task() 121 122static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end) 123{ 124 flush_tlb_mm(vma->vm_mm); 125} 126 127#define TLBSTATE_OK 1 128#define TLBSTATE_LAZY 2 129 130struct tlb_state 131{ 132 struct mm_struct *active_mm; 133 int state; 134 char __cacheline_padding[L1_CACHE_BYTES-8]; 135}; 136DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate); 137 138 139#endif 140 141#define flush_tlb_kernel_range(start, end) flush_tlb_all() 142 143static inline void flush_tlb_pgtables(struct mm_struct *mm, 144 unsigned long start, unsigned long end) 145{ 146 /* i386 does not keep any page table caches in TLB */ 147} 148 149#endif /* _I386_TLBFLUSH_H */