diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-01-30 07:32:58 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:32:58 -0500 |
commit | 195466dc4b9b8a4cc89d37ea1211746f3afbc941 (patch) | |
tree | 38a4dc9e105d54cf285cdcbc141b424a2fc16f41 /include/asm-x86/pgtable.h | |
parent | e33287013585e96180c575288bf1db22bee47b52 (diff) |
x86: pgtable: unify pte accessors
Make various pte accessors common.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/asm-x86/pgtable.h')
-rw-r--r-- | include/asm-x86/pgtable.h | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 6452286e71a1..62fa856c2491 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h | |||
@@ -116,6 +116,7 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; | |||
116 | #define __S111 PAGE_SHARED_EXEC | 116 | #define __S111 PAGE_SHARED_EXEC |
117 | 117 | ||
118 | #ifndef __ASSEMBLY__ | 118 | #ifndef __ASSEMBLY__ |
119 | |||
119 | /* | 120 | /* |
120 | * The following only work if pte_present() is true. | 121 | * The following only work if pte_present() is true. |
121 | * Undefined behaviour if not.. | 122 | * Undefined behaviour if not.. |
@@ -169,7 +170,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
169 | return __pte(val); | 170 | return __pte(val); |
170 | } | 171 | } |
171 | 172 | ||
172 | |||
173 | #endif /* __ASSEMBLY__ */ | 173 | #endif /* __ASSEMBLY__ */ |
174 | 174 | ||
175 | #ifdef CONFIG_X86_32 | 175 | #ifdef CONFIG_X86_32 |
@@ -178,4 +178,112 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
178 | # include "pgtable_64.h" | 178 | # include "pgtable_64.h" |
179 | #endif | 179 | #endif |
180 | 180 | ||
181 | #ifndef __ASSEMBLY__ | ||
182 | |||
183 | #ifndef CONFIG_PARAVIRT | ||
184 | /* | ||
185 | * Rules for using pte_update - it must be called after any PTE update which | ||
186 | * has not been done using the set_pte / clear_pte interfaces. It is used by | ||
187 | * shadow mode hypervisors to resynchronize the shadow page tables. Kernel PTE | ||
188 | * updates should either be sets, clears, or set_pte_atomic for P->P | ||
189 | * transitions, which means this hook should only be called for user PTEs. | ||
190 | * This hook implies a P->P protection or access change has taken place, which | ||
191 | * requires a subsequent TLB flush. The notification can optionally be delayed | ||
192 | * until the TLB flush event by using the pte_update_defer form of the | ||
193 | * interface, but care must be taken to assure that the flush happens while | ||
194 | * still holding the same page table lock so that the shadow and primary pages | ||
195 | * do not become out of sync on SMP. | ||
196 | */ | ||
197 | #define pte_update(mm, addr, ptep) do { } while (0) | ||
198 | #define pte_update_defer(mm, addr, ptep) do { } while (0) | ||
199 | #endif | ||
200 | |||
201 | /* local pte updates need not use xchg for locking */ | ||
202 | static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) | ||
203 | { | ||
204 | pte_t res = *ptep; | ||
205 | |||
206 | /* Pure native function needs no input for mm, addr */ | ||
207 | native_pte_clear(NULL, 0, ptep); | ||
208 | return res; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * We only update the dirty/accessed state if we set | ||
213 | * the dirty bit by hand in the kernel, since the hardware | ||
214 | * will do the accessed bit for us, and we don't want to | ||
215 | * race with other CPU's that might be updating the dirty | ||
216 | * bit at the same time. | ||
217 | */ | ||
218 | #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS | ||
219 | #define ptep_set_access_flags(vma, address, ptep, entry, dirty) \ | ||
220 | ({ \ | ||
221 | int __changed = !pte_same(*(ptep), entry); \ | ||
222 | if (__changed && dirty) { \ | ||
223 | *ptep = entry; \ | ||
224 | pte_update_defer((vma)->vm_mm, (address), (ptep)); \ | ||
225 | flush_tlb_page(vma, address); \ | ||
226 | } \ | ||
227 | __changed; \ | ||
228 | }) | ||
229 | |||
230 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | ||
231 | #define ptep_test_and_clear_young(vma, addr, ptep) ({ \ | ||
232 | int __ret = 0; \ | ||
233 | if (pte_young(*(ptep))) \ | ||
234 | __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, \ | ||
235 | &(ptep)->pte); \ | ||
236 | if (__ret) \ | ||
237 | pte_update((vma)->vm_mm, addr, ptep); \ | ||
238 | __ret; \ | ||
239 | }) | ||
240 | |||
241 | #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH | ||
242 | #define ptep_clear_flush_young(vma, address, ptep) \ | ||
243 | ({ \ | ||
244 | int __young; \ | ||
245 | __young = ptep_test_and_clear_young((vma), (address), (ptep)); \ | ||
246 | if (__young) \ | ||
247 | flush_tlb_page(vma, address); \ | ||
248 | __young; \ | ||
249 | }) | ||
250 | |||
251 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR | ||
252 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | ||
253 | { | ||
254 | pte_t pte = native_ptep_get_and_clear(ptep); | ||
255 | pte_update(mm, addr, ptep); | ||
256 | return pte; | ||
257 | } | ||
258 | |||
259 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL | ||
260 | static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) | ||
261 | { | ||
262 | pte_t pte; | ||
263 | if (full) { | ||
264 | /* | ||
265 | * Full address destruction in progress; paravirt does not | ||
266 | * care about updates and native needs no locking | ||
267 | */ | ||
268 | pte = native_local_ptep_get_and_clear(ptep); | ||
269 | } else { | ||
270 | pte = ptep_get_and_clear(mm, addr, ptep); | ||
271 | } | ||
272 | return pte; | ||
273 | } | ||
274 | |||
275 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT | ||
276 | static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | ||
277 | { | ||
278 | clear_bit(_PAGE_BIT_RW, &ptep->pte); | ||
279 | pte_update(mm, addr, ptep); | ||
280 | } | ||
281 | |||
282 | #ifndef CONFIG_PARAVIRT | ||
283 | #define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) | ||
284 | #endif /* !CONFIG_PARAVIRT */ | ||
285 | |||
286 | #include <asm-generic/pgtable.h> | ||
287 | #endif /* __ASSEMBLY__ */ | ||
288 | |||
181 | #endif /* _ASM_X86_PGTABLE_H */ | 289 | #endif /* _ASM_X86_PGTABLE_H */ |