Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / include / arch-generic / pgtable.h
1 #ifndef _ASM_GENERIC_PGTABLE_H
2 #define _ASM_GENERIC_PGTABLE_H
3
4 #ifndef __HAVE_ARCH_PTEP_ESTABLISH
5 /*
6  * Establish a new mapping:
7  *  - flush the old one
8  *  - update the page tables
9  *  - inform the TLB about the new one
10  *
11  * We hold the mm semaphore for reading, and the pte lock.
12  *
13  * Note: the old pte is known to not be writable, so we don't need to
14  * worry about dirty bits etc getting lost.
15  */
16 #ifndef __HAVE_ARCH_SET_PTE_ATOMIC
17 #define ptep_establish(__vma, __address, __ptep, __entry)               \
18 do {                                                                    \
19         set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);       \
20         flush_tlb_page(__vma, __address);                               \
21 } while (0)
22 #else /* __HAVE_ARCH_SET_PTE_ATOMIC */
23 #define ptep_establish(__vma, __address, __ptep, __entry)               \
24 do {                                                                    \
25         set_pte_atomic(__ptep, __entry);                                \
26         flush_tlb_page(__vma, __address);                               \
27 } while (0)
28 #endif /* __HAVE_ARCH_SET_PTE_ATOMIC */
29 #endif
30
31 #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
32 /*
33  * Largely same as above, but only sets the access flags (dirty,
34  * accessed, and writable). Furthermore, we know it always gets set
35  * to a "more permissive" setting, which allows most architectures
36  * to optimize this.
37  */
38 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
39 do {                                                                      \
40         set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);         \
41         flush_tlb_page(__vma, __address);                                 \
42 } while (0)
43 #endif
44
45 #ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
46 #define ptep_test_and_clear_young(__vma, __address, __ptep)             \
47 ({                                                                      \
48         pte_t __pte = *(__ptep);                                        \
49         int r = 1;                                                      \
50         if (!pte_young(__pte))                                          \
51                 r = 0;                                                  \
52         else                                                            \
53                 set_pte_at((__vma)->vm_mm, (__address),                 \
54                            (__ptep), pte_mkold(__pte));                 \
55         r;                                                              \
56 })
57 #endif
58
59 #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
60 #define ptep_clear_flush_young(__vma, __address, __ptep)                \
61 ({                                                                      \
62         int __young;                                                    \
63         __young = ptep_test_and_clear_young(__vma, __address, __ptep);  \
64         if (__young)                                                    \
65                 flush_tlb_page(__vma, __address);                       \
66         __young;                                                        \
67 })
68 #endif
69
70 #ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
71 #define ptep_test_and_clear_dirty(__vma, __address, __ptep)             \
72 ({                                                                      \
73         pte_t __pte = *__ptep;                                          \
74         int r = 1;                                                      \
75         if (!pte_dirty(__pte))                                          \
76                 r = 0;                                                  \
77         else                                                            \
78                 set_pte_at((__vma)->vm_mm, (__address), (__ptep),       \
79                            pte_mkclean(__pte));                         \
80         r;                                                              \
81 })
82 #endif
83
84 #ifndef __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
85 #define ptep_clear_flush_dirty(__vma, __address, __ptep)                \
86 ({                                                                      \
87         int __dirty;                                                    \
88         __dirty = ptep_test_and_clear_dirty(__vma, __address, __ptep);  \
89         if (__dirty)                                                    \
90                 flush_tlb_page(__vma, __address);                       \
91         __dirty;                                                        \
92 })
93 #endif
94
95 #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
96 #define ptep_get_and_clear(__mm, __address, __ptep)                     \
97 ({                                                                      \
98         pte_t __pte = *(__ptep);                                        \
99         pte_clear((__mm), (__address), (__ptep));                       \
100         __pte;                                                          \
101 })
102 #endif
103
104 #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
105 #define ptep_get_and_clear_full(__mm, __address, __ptep, __full)        \
106 ({                                                                      \
107         pte_t __pte;                                                    \
108         __pte = ptep_get_and_clear((__mm), (__address), (__ptep));      \
109         __pte;                                                          \
110 })
111 #endif
112
113 #ifndef __HAVE_ARCH_PTE_CLEAR_FULL
114 #define pte_clear_full(__mm, __address, __ptep, __full)                 \
115 do {                                                                    \
116         pte_clear((__mm), (__address), (__ptep));                       \
117 } while (0)
118 #endif
119
120 #ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
121 #define ptep_clear_flush(__vma, __address, __ptep)                      \
122 ({                                                                      \
123         pte_t __pte;                                                    \
124         __pte = ptep_get_and_clear((__vma)->vm_mm, __address, __ptep);  \
125         flush_tlb_page(__vma, __address);                               \
126         __pte;                                                          \
127 })
128 #endif
129
130 #ifndef __HAVE_ARCH_PTEP_SET_WRPROTECT
131 struct mm_struct;
132 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
133 {
134         pte_t old_pte = *ptep;
135         set_pte_at(mm, address, ptep, pte_wrprotect(old_pte));
136 }
137 #endif
138
139 #ifndef __HAVE_ARCH_PTE_SAME
140 #define pte_same(A,B)   (pte_val(A) == pte_val(B))
141 #endif
142
143 #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
144 #define page_test_and_clear_dirty(page) (0)
145 #define pte_maybe_dirty(pte)            pte_dirty(pte)
146 #else
147 #define pte_maybe_dirty(pte)            (1)
148 #endif
149
150 #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
151 #define page_test_and_clear_young(page) (0)
152 #endif
153
154 #ifndef __HAVE_ARCH_PGD_OFFSET_GATE
155 #define pgd_offset_gate(mm, addr)       pgd_offset(mm, addr)
156 #endif
157
158 #ifndef __HAVE_ARCH_LAZY_MMU_PROT_UPDATE
159 #define lazy_mmu_prot_update(pte)       do { } while (0)
160 #endif
161
162 #ifndef __HAVE_ARCH_MOVE_PTE
163 #define move_pte(pte, prot, old_addr, new_addr) (pte)
164 #endif
165
166 /*
167  * When walking page tables, get the address of the next boundary,
168  * or the end address of the range if that comes earlier.  Although no
169  * vma end wraps to 0, rounded up __boundary may wrap to 0 throughout.
170  */
171
172 #define pgd_addr_end(addr, end)                                         \
173 ({      unsigned long __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK;  \
174         (__boundary - 1 < (end) - 1)? __boundary: (end);                \
175 })
176
177 #ifndef pud_addr_end
178 #define pud_addr_end(addr, end)                                         \
179 ({      unsigned long __boundary = ((addr) + PUD_SIZE) & PUD_MASK;      \
180         (__boundary - 1 < (end) - 1)? __boundary: (end);                \
181 })
182 #endif
183
184 #ifndef pmd_addr_end
185 #define pmd_addr_end(addr, end)                                         \
186 ({      unsigned long __boundary = ((addr) + PMD_SIZE) & PMD_MASK;      \
187         (__boundary - 1 < (end) - 1)? __boundary: (end);                \
188 })
189 #endif
190
191 #ifndef __ASSEMBLY__
192 /*
193  * When walking page tables, we usually want to skip any p?d_none entries;
194  * and any p?d_bad entries - reporting the error before resetting to none.
195  * Do the tests inline, but report and clear the bad entry in mm/memory.c.
196  */
197 void pgd_clear_bad(pgd_t *);
198 void pud_clear_bad(pud_t *);
199 void pmd_clear_bad(pmd_t *);
200
201 static inline int pgd_none_or_clear_bad(pgd_t *pgd)
202 {
203         if (pgd_none(*pgd))
204                 return 1;
205         if (unlikely(pgd_bad(*pgd))) {
206                 pgd_clear_bad(pgd);
207                 return 1;
208         }
209         return 0;
210 }
211
212 static inline int pud_none_or_clear_bad(pud_t *pud)
213 {
214         if (pud_none(*pud))
215                 return 1;
216         if (unlikely(pud_bad(*pud))) {
217                 pud_clear_bad(pud);
218                 return 1;
219         }
220         return 0;
221 }
222
223 static inline int pmd_none_or_clear_bad(pmd_t *pmd)
224 {
225         if (pmd_none(*pmd))
226                 return 1;
227         if (unlikely(pmd_bad(*pmd))) {
228                 pmd_clear_bad(pmd);
229                 return 1;
230         }
231         return 0;
232 }
233 #endif /* !__ASSEMBLY__ */
234
235 #endif /* _ASM_GENERIC_PGTABLE_H */