fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / asm-x86_64 / mach-xen / asm / tlbflush.h
1 #ifndef _X8664_TLBFLUSH_H
2 #define _X8664_TLBFLUSH_H
3
4 #include <linux/mm.h>
5 #include <asm/processor.h>
6
7 static inline unsigned long get_cr3(void)
8 {
9         unsigned long cr3;
10         asm volatile("mov %%cr3,%0" : "=r" (cr3));
11         return machine_to_phys(cr3);
12 }
13
14 static inline void set_cr3(unsigned long cr3)
15 {
16         BUG();
17         /* What the hell is this supposed to do: JQ */
18         asm volatile("mov %0,%%cr3" :: "r" (cr3) : "memory");
19 }
20
21 #define __flush_tlb()   xen_tlb_flush()
22
23 static inline unsigned long get_cr4(void)
24 {
25         unsigned long cr4;
26         asm volatile("mov %%cr4,%0" : "=r" (cr4));
27         return cr4;
28 }
29
30 static inline void set_cr4(unsigned long cr4)
31 {
32         asm volatile("mov %0,%%cr4" :: "r" (cr4) : "memory");
33 }
34
35 #define __flush_tlb_all() xen_tlb_flush()
36
37 #define __flush_tlb_one(addr)   xen_invlpg((unsigned long)addr)
38
39
40 /*
41  * TLB flushing:
42  *
43  *  - flush_tlb() flushes the current mm struct TLBs
44  *  - flush_tlb_all() flushes all processes TLBs
45  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
46  *  - flush_tlb_page(vma, vmaddr) flushes one page
47  *  - flush_tlb_range(vma, start, end) flushes a range of pages
48  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
49  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
50  *
51  * x86-64 can only flush individual pages or full VMs. For a range flush
52  * we always do the full VM. Might be worth trying if for a small
53  * range a few INVLPGs in a row are a win.
54  */
55
56 #ifndef CONFIG_SMP
57
58 #define flush_tlb() __flush_tlb()
59 #define flush_tlb_all() __flush_tlb_all()
60 #define local_flush_tlb() __flush_tlb()
61
62 static inline void flush_tlb_mm(struct mm_struct *mm)
63 {
64         if (mm == current->active_mm)
65                 __flush_tlb();
66 }
67
68 static inline void flush_tlb_page(struct vm_area_struct *vma,
69         unsigned long addr)
70 {
71         if (vma->vm_mm == current->active_mm)
72                 __flush_tlb_one(addr);
73 }
74
75 static inline void flush_tlb_range(struct vm_area_struct *vma,
76         unsigned long start, unsigned long end)
77 {
78         if (vma->vm_mm == current->active_mm)
79                 __flush_tlb();
80 }
81
82 #else
83
84 #include <asm/smp.h>
85
86 #define local_flush_tlb() \
87         __flush_tlb()
88
89 extern void flush_tlb_all(void);
90 extern void flush_tlb_current_task(void);
91 extern void flush_tlb_mm(struct mm_struct *);
92 extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
93
94 #define flush_tlb()     flush_tlb_current_task()
95
96 static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
97 {
98         flush_tlb_mm(vma->vm_mm);
99 }
100
101 #define TLBSTATE_OK     1
102 #define TLBSTATE_LAZY   2
103
104 /* Roughly an IPI every 20MB with 4k pages for freeing page table
105    ranges. Cost is about 42k of memory for each CPU. */
106 #define ARCH_FREE_PTE_NR 5350   
107
108 #endif
109
110 #define flush_tlb_kernel_range(start, end) flush_tlb_all()
111
112 static inline void flush_tlb_pgtables(struct mm_struct *mm,
113                                       unsigned long start, unsigned long end)
114 {
115         /* x86_64 does not keep any page table caches in a software TLB.
116            The CPUs do in their hardware TLBs, but they are handled
117            by the normal TLB flushing algorithms. */
118 }
119
120 #endif /* _X8664_TLBFLUSH_H */