home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-x86_64 / tlbflush.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  3.4 KB  |  128 lines

  1. #ifndef _X8664_TLBFLUSH_H
  2. #define _X8664_TLBFLUSH_H
  3.  
  4. #include <linux/mm.h>
  5. #include <asm/processor.h>
  6.  
  7. #define __flush_tlb()                            \
  8.     do {                                \
  9.         unsigned long tmpreg;                    \
  10.                                     \
  11.         __asm__ __volatile__(                    \
  12.             "movq %%cr3, %0;  # flush TLB \n"        \
  13.             "movq %0, %%cr3;              \n"        \
  14.             : "=r" (tmpreg)                    \
  15.             :: "memory");                    \
  16.     } while (0)
  17.  
  18. /*
  19.  * Global pages have to be flushed a bit differently. Not a real
  20.  * performance problem because this does not happen often.
  21.  */
  22. #define __flush_tlb_global()                        \
  23.     do {                                \
  24.         unsigned long tmpreg, cr4, cr4_orig;            \
  25.                                     \
  26.         __asm__ __volatile__(                    \
  27.             "movq %%cr4, %2;  # turn off PGE     \n"    \
  28.             "movq %2, %1;                        \n"    \
  29.             "andq %3, %1;                        \n"    \
  30.             "movq %1, %%cr4;                     \n"    \
  31.             "movq %%cr3, %0;  # flush TLB        \n"    \
  32.             "movq %0, %%cr3;                     \n"    \
  33.             "movq %2, %%cr4;  # turn PGE back on \n"    \
  34.             : "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig)    \
  35.             : "i" (~X86_CR4_PGE)                \
  36.             : "memory");                    \
  37.     } while (0)
  38.  
  39. extern unsigned long pgkern_mask;
  40.  
  41. #define __flush_tlb_all() __flush_tlb_global()
  42.  
  43. #define __flush_tlb_one(addr) \
  44.     __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
  45.  
  46.  
  47. /*
  48.  * TLB flushing:
  49.  *
  50.  *  - flush_tlb() flushes the current mm struct TLBs
  51.  *  - flush_tlb_all() flushes all processes TLBs
  52.  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
  53.  *  - flush_tlb_page(vma, vmaddr) flushes one page
  54.  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  55.  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
  56.  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  57.  *
  58.  * x86-64 can only flush individual pages or full VMs. For a range flush
  59.  * we always do the full VM. Might be worth trying if for a small
  60.  * range a few INVLPGs in a row are a win.
  61.  */
  62.  
  63. #ifndef CONFIG_SMP
  64.  
  65. #define flush_tlb() __flush_tlb()
  66. #define flush_tlb_all() __flush_tlb_all()
  67. #define local_flush_tlb() __flush_tlb()
  68.  
  69. static inline void flush_tlb_mm(struct mm_struct *mm)
  70. {
  71.     if (mm == current->active_mm)
  72.         __flush_tlb();
  73. }
  74.  
  75. static inline void flush_tlb_page(struct vm_area_struct *vma,
  76.     unsigned long addr)
  77. {
  78.     if (vma->vm_mm == current->active_mm)
  79.         __flush_tlb_one(addr);
  80. }
  81.  
  82. static inline void flush_tlb_range(struct vm_area_struct *vma,
  83.     unsigned long start, unsigned long end)
  84. {
  85.     if (vma->vm_mm == current->active_mm)
  86.         __flush_tlb();
  87. }
  88.  
  89. #else
  90.  
  91. #include <asm/smp.h>
  92.  
  93. #define local_flush_tlb() \
  94.     __flush_tlb()
  95.  
  96. extern void flush_tlb_all(void);
  97. extern void flush_tlb_current_task(void);
  98. extern void flush_tlb_mm(struct mm_struct *);
  99. extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
  100.  
  101. #define flush_tlb()    flush_tlb_current_task()
  102.  
  103. static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
  104. {
  105.     flush_tlb_mm(vma->vm_mm);
  106. }
  107.  
  108. #define TLBSTATE_OK    1
  109. #define TLBSTATE_LAZY    2
  110.  
  111. /* Roughly an IPI every 20MB with 4k pages for freeing page table
  112.    ranges. Cost is about 42k of memory for each CPU. */
  113. #define ARCH_FREE_PTE_NR 5350    
  114.  
  115. #endif
  116.  
  117. #define flush_tlb_kernel_range(start, end) flush_tlb_all()
  118.  
  119. static inline void flush_tlb_pgtables(struct mm_struct *mm,
  120.                       unsigned long start, unsigned long end)
  121. {
  122.     /* x86_64 does not keep any page table caches in a software TLB.
  123.        The CPUs do in their hardware TLBs, but they are handled
  124.        by the normal TLB flushing algorithms. */
  125. }
  126.  
  127. #endif /* _X8664_TLBFLUSH_H */
  128.