Blame view

include/asm-generic/pgtable.h 12.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  #ifndef _ASM_GENERIC_PGTABLE_H
  #define _ASM_GENERIC_PGTABLE_H
673eae823   Rusty Russell   [PATCH] x86: triv...
3
  #ifndef __ASSEMBLY__
9535239f6   Greg Ungerer   changing include/...
4
  #ifdef CONFIG_MMU
673eae823   Rusty Russell   [PATCH] x86: triv...
5

fbd718448   Ben Hutchings   mm: <asm-generic/...
6
  #include <linux/mm_types.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
  #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
8
9
10
11
12
13
14
15
16
  extern int ptep_set_access_flags(struct vm_area_struct *vma,
  				 unsigned long address, pte_t *ptep,
  				 pte_t entry, int dirty);
  #endif
  
  #ifndef __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
  extern int pmdp_set_access_flags(struct vm_area_struct *vma,
  				 unsigned long address, pmd_t *pmdp,
  				 pmd_t entry, int dirty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
  #endif
  
  #ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
  					    unsigned long address,
  					    pte_t *ptep)
  {
  	pte_t pte = *ptep;
  	int r = 1;
  	if (!pte_young(pte))
  		r = 0;
  	else
  		set_pte_at(vma->vm_mm, address, ptep, pte_mkold(pte));
  	return r;
  }
  #endif
  
  #ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
  					    unsigned long address,
  					    pmd_t *pmdp)
  {
  	pmd_t pmd = *pmdp;
  	int r = 1;
  	if (!pmd_young(pmd))
  		r = 0;
  	else
  		set_pmd_at(vma->vm_mm, address, pmdp, pmd_mkold(pmd));
  	return r;
  }
  #else /* CONFIG_TRANSPARENT_HUGEPAGE */
  static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
  					    unsigned long address,
  					    pmd_t *pmdp)
  {
  	BUG();
  	return 0;
  }
  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
  #endif
  
  #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
60
61
62
63
64
65
66
  int ptep_clear_flush_young(struct vm_area_struct *vma,
  			   unsigned long address, pte_t *ptep);
  #endif
  
  #ifndef __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
  int pmdp_clear_flush_young(struct vm_area_struct *vma,
  			   unsigned long address, pmd_t *pmdp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
  #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
  				       unsigned long address,
  				       pte_t *ptep)
  {
  	pte_t pte = *ptep;
  	pte_clear(mm, address, ptep);
  	return pte;
  }
  #endif
  
  #ifndef __HAVE_ARCH_PMDP_GET_AND_CLEAR
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
  				       unsigned long address,
  				       pmd_t *pmdp)
  {
  	pmd_t pmd = *pmdp;
  	pmd_clear(mm, address, pmdp);
  	return pmd;
49b24d6b4   Nicolas Kaiser   include/asm-gener...
88
  }
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
89
  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
  #endif
a600388d2   Zachary Amsden   [PATCH] x86: ptep...
91
  #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
92
93
94
95
96
97
98
99
  static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
  					    unsigned long address, pte_t *ptep,
  					    int full)
  {
  	pte_t pte;
  	pte = ptep_get_and_clear(mm, address, ptep);
  	return pte;
  }
a600388d2   Zachary Amsden   [PATCH] x86: ptep...
100
  #endif
9888a1cae   Zachary Amsden   [PATCH] paravirt:...
101
102
103
104
105
106
  /*
   * Some architectures may be able to avoid expensive synchronization
   * primitives when modifications are made to PTE's which are already
   * not present, or in the process of an address space destruction.
   */
  #ifndef __HAVE_ARCH_PTE_CLEAR_NOT_PRESENT_FULL
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
107
108
109
110
111
112
113
  static inline void pte_clear_not_present_full(struct mm_struct *mm,
  					      unsigned long address,
  					      pte_t *ptep,
  					      int full)
  {
  	pte_clear(mm, address, ptep);
  }
a600388d2   Zachary Amsden   [PATCH] x86: ptep...
114
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
  #ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
116
117
118
119
120
121
122
123
124
  extern pte_t ptep_clear_flush(struct vm_area_struct *vma,
  			      unsigned long address,
  			      pte_t *ptep);
  #endif
  
  #ifndef __HAVE_ARCH_PMDP_CLEAR_FLUSH
  extern pmd_t pmdp_clear_flush(struct vm_area_struct *vma,
  			      unsigned long address,
  			      pmd_t *pmdp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
  #endif
  
  #ifndef __HAVE_ARCH_PTEP_SET_WRPROTECT
8c65b4a60   Tim Schmielau   [PATCH] fix remai...
128
  struct mm_struct;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
134
  static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
  {
  	pte_t old_pte = *ptep;
  	set_pte_at(mm, address, ptep, pte_wrprotect(old_pte));
  }
  #endif
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  #ifndef __HAVE_ARCH_PMDP_SET_WRPROTECT
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  static inline void pmdp_set_wrprotect(struct mm_struct *mm,
  				      unsigned long address, pmd_t *pmdp)
  {
  	pmd_t old_pmd = *pmdp;
  	set_pmd_at(mm, address, pmdp, pmd_wrprotect(old_pmd));
  }
  #else /* CONFIG_TRANSPARENT_HUGEPAGE */
  static inline void pmdp_set_wrprotect(struct mm_struct *mm,
  				      unsigned long address, pmd_t *pmdp)
  {
  	BUG();
  }
  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
  #endif
  
  #ifndef __HAVE_ARCH_PMDP_SPLITTING_FLUSH
b3697c025   Andrea Arcangeli   fix non-x86 build...
153
154
155
  extern pmd_t pmdp_splitting_flush(struct vm_area_struct *vma,
  				  unsigned long address,
  				  pmd_t *pmdp);
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
156
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  #ifndef __HAVE_ARCH_PTE_SAME
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
  static inline int pte_same(pte_t pte_a, pte_t pte_b)
  {
  	return pte_val(pte_a) == pte_val(pte_b);
  }
  #endif
  
  #ifndef __HAVE_ARCH_PMD_SAME
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
  {
  	return pmd_val(pmd_a) == pmd_val(pmd_b);
  }
  #else /* CONFIG_TRANSPARENT_HUGEPAGE */
  static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
  {
  	BUG();
  	return 0;
  }
  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
  #endif
2d42552d1   Martin Schwidefsky   [S390] merge page...
178
179
  #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
  #define page_test_and_clear_dirty(pfn, mapped)	(0)
6c210482a   Martin Schwidefsky   [S390] split page...
180
  #endif
2d42552d1   Martin Schwidefsky   [S390] merge page...
181
  #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
b4955ce3d   Abhijit Karmarkar   [PATCH] msync: ch...
182
183
184
  #define pte_maybe_dirty(pte)		pte_dirty(pte)
  #else
  #define pte_maybe_dirty(pte)		(1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
186
187
  #endif
  
  #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
2d42552d1   Martin Schwidefsky   [S390] merge page...
188
  #define page_test_and_clear_young(pfn) (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
190
191
192
193
  #endif
  
  #ifndef __HAVE_ARCH_PGD_OFFSET_GATE
  #define pgd_offset_gate(mm, addr)	pgd_offset(mm, addr)
  #endif
0b0968a3e   David S. Miller   [SPARC64]: Fix D-...
194
  #ifndef __HAVE_ARCH_MOVE_PTE
8b1f31246   Nick Piggin   [PATCH] mm: move_...
195
  #define move_pte(pte, prot, old_addr, new_addr)	(pte)
8b1f31246   Nick Piggin   [PATCH] mm: move_...
196
  #endif
61c77326d   Shaohua Li   x86, mm: Avoid un...
197
198
199
  #ifndef flush_tlb_fix_spurious_fault
  #define flush_tlb_fix_spurious_fault(vma, address) flush_tlb_page(vma, address)
  #endif
0634a632f   Paul Mundt   asm-generic: add ...
200
201
202
  #ifndef pgprot_noncached
  #define pgprot_noncached(prot)	(prot)
  #endif
2520bd312   venkatesh.pallipadi@intel.com   x86: PAT: add pgp...
203
204
205
  #ifndef pgprot_writecombine
  #define pgprot_writecombine pgprot_noncached
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  /*
8f6c99c11   Hugh Dickins   [PATCH] freepgt: ...
207
208
209
   * When walking page tables, get the address of the next boundary,
   * or the end address of the range if that comes earlier.  Although no
   * vma end wraps to 0, rounded up __boundary may wrap to 0 throughout.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
213
214
  #define pgd_addr_end(addr, end)						\
  ({	unsigned long __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK;	\
  	(__boundary - 1 < (end) - 1)? __boundary: (end);		\
  })
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  
  #ifndef pud_addr_end
  #define pud_addr_end(addr, end)						\
  ({	unsigned long __boundary = ((addr) + PUD_SIZE) & PUD_MASK;	\
  	(__boundary - 1 < (end) - 1)? __boundary: (end);		\
  })
  #endif
  
  #ifndef pmd_addr_end
  #define pmd_addr_end(addr, end)						\
  ({	unsigned long __boundary = ((addr) + PMD_SIZE) & PMD_MASK;	\
  	(__boundary - 1 < (end) - 1)? __boundary: (end);		\
  })
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  /*
   * When walking page tables, we usually want to skip any p?d_none entries;
   * and any p?d_bad entries - reporting the error before resetting to none.
   * Do the tests inline, but report and clear the bad entry in mm/memory.c.
   */
  void pgd_clear_bad(pgd_t *);
  void pud_clear_bad(pud_t *);
  void pmd_clear_bad(pmd_t *);
  
  static inline int pgd_none_or_clear_bad(pgd_t *pgd)
  {
  	if (pgd_none(*pgd))
  		return 1;
  	if (unlikely(pgd_bad(*pgd))) {
  		pgd_clear_bad(pgd);
  		return 1;
  	}
  	return 0;
  }
  
  static inline int pud_none_or_clear_bad(pud_t *pud)
  {
  	if (pud_none(*pud))
  		return 1;
  	if (unlikely(pud_bad(*pud))) {
  		pud_clear_bad(pud);
  		return 1;
  	}
  	return 0;
  }
  
  static inline int pmd_none_or_clear_bad(pmd_t *pmd)
  {
  	if (pmd_none(*pmd))
  		return 1;
  	if (unlikely(pmd_bad(*pmd))) {
  		pmd_clear_bad(pmd);
  		return 1;
  	}
  	return 0;
  }
9535239f6   Greg Ungerer   changing include/...
270

1ea0704e0   Jeremy Fitzhardinge   mm: add a ptep_mo...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  static inline pte_t __ptep_modify_prot_start(struct mm_struct *mm,
  					     unsigned long addr,
  					     pte_t *ptep)
  {
  	/*
  	 * Get the current pte state, but zero it out to make it
  	 * non-present, preventing the hardware from asynchronously
  	 * updating it.
  	 */
  	return ptep_get_and_clear(mm, addr, ptep);
  }
  
  static inline void __ptep_modify_prot_commit(struct mm_struct *mm,
  					     unsigned long addr,
  					     pte_t *ptep, pte_t pte)
  {
  	/*
  	 * The pte is non-present, so there's no hardware state to
  	 * preserve.
  	 */
  	set_pte_at(mm, addr, ptep, pte);
  }
  
  #ifndef __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
  /*
   * Start a pte protection read-modify-write transaction, which
   * protects against asynchronous hardware modifications to the pte.
   * The intention is not to prevent the hardware from making pte
   * updates, but to prevent any updates it may make from being lost.
   *
   * This does not protect against other software modifications of the
   * pte; the appropriate pte lock must be held over the transation.
   *
   * Note that this interface is intended to be batchable, meaning that
   * ptep_modify_prot_commit may not actually update the pte, but merely
   * queue the update to be done at some later time.  The update must be
   * actually committed before the pte lock is released, however.
   */
  static inline pte_t ptep_modify_prot_start(struct mm_struct *mm,
  					   unsigned long addr,
  					   pte_t *ptep)
  {
  	return __ptep_modify_prot_start(mm, addr, ptep);
  }
  
  /*
   * Commit an update to a pte, leaving any hardware-controlled bits in
   * the PTE unmodified.
   */
  static inline void ptep_modify_prot_commit(struct mm_struct *mm,
  					   unsigned long addr,
  					   pte_t *ptep, pte_t pte)
  {
  	__ptep_modify_prot_commit(mm, addr, ptep, pte);
  }
  #endif /* __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION */
fe1a6875f   Sebastian Siewior   mm: fix build on ...
327
  #endif /* CONFIG_MMU */
1ea0704e0   Jeremy Fitzhardinge   mm: add a ptep_mo...
328

9535239f6   Greg Ungerer   changing include/...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  /*
   * A facility to provide lazy MMU batching.  This allows PTE updates and
   * page invalidations to be delayed until a call to leave lazy MMU mode
   * is issued.  Some architectures may benefit from doing this, and it is
   * beneficial for both shadow and direct mode hypervisors, which may batch
   * the PTE updates which happen during this window.  Note that using this
   * interface requires that read hazards be removed from the code.  A read
   * hazard could result in the direct mode hypervisor case, since the actual
   * write to the page tables may not yet have taken place, so reads though
   * a raw PTE pointer after it has been modified are not guaranteed to be
   * up to date.  This mode can only be entered and left under the protection of
   * the page table locks for all page tables which may be modified.  In the UP
   * case, this is required so that preemption is disabled, and in the SMP case,
   * it must synchronize the delayed page table writes properly on other CPUs.
   */
  #ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
  #define arch_enter_lazy_mmu_mode()	do {} while (0)
  #define arch_leave_lazy_mmu_mode()	do {} while (0)
  #define arch_flush_lazy_mmu_mode()	do {} while (0)
  #endif
  
  /*
7fd7d83d4   Jeremy Fitzhardinge   x86/pvops: replac...
351
352
353
354
355
356
357
358
359
   * A facility to provide batching of the reload of page tables and
   * other process state with the actual context switch code for
   * paravirtualized guests.  By convention, only one of the batched
   * update (lazy) modes (CPU, MMU) should be active at any given time,
   * entry should never be nested, and entry and exits should always be
   * paired.  This is for sanity of maintaining and reasoning about the
   * kernel code.  In this case, the exit (end of the context switch) is
   * in architecture-specific code, and so doesn't need a generic
   * definition.
9535239f6   Greg Ungerer   changing include/...
360
   */
7fd7d83d4   Jeremy Fitzhardinge   x86/pvops: replac...
361
  #ifndef __HAVE_ARCH_START_CONTEXT_SWITCH
224101ed6   Jeremy Fitzhardinge   x86/paravirt: fin...
362
  #define arch_start_context_switch(prev)	do {} while (0)
9535239f6   Greg Ungerer   changing include/...
363
  #endif
34801ba9b   venkatesh.pallipadi@intel.com   x86: PAT: move tr...
364
365
366
367
368
369
370
371
  #ifndef __HAVE_PFNMAP_TRACKING
  /*
   * Interface that can be used by architecture code to keep track of
   * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
   *
   * track_pfn_vma_new is called when a _new_ pfn mapping is being established
   * for physical range indicated by pfn and size.
   */
e4b866ed1   venkatesh.pallipadi@intel.com   x86 PAT: change t...
372
  static inline int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
34801ba9b   venkatesh.pallipadi@intel.com   x86: PAT: move tr...
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
  					unsigned long pfn, unsigned long size)
  {
  	return 0;
  }
  
  /*
   * Interface that can be used by architecture code to keep track of
   * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
   *
   * track_pfn_vma_copy is called when vma that is covering the pfnmap gets
   * copied through copy_page_range().
   */
  static inline int track_pfn_vma_copy(struct vm_area_struct *vma)
  {
  	return 0;
  }
  
  /*
   * Interface that can be used by architecture code to keep track of
   * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
   *
   * untrack_pfn_vma is called while unmapping a pfnmap for a region.
   * untrack can be called for a specific region indicated by pfn and size or
   * can be for the entire vma (in which case size can be zero).
   */
  static inline void untrack_pfn_vma(struct vm_area_struct *vma,
  					unsigned long pfn, unsigned long size)
  {
  }
  #else
e4b866ed1   venkatesh.pallipadi@intel.com   x86 PAT: change t...
403
  extern int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
34801ba9b   venkatesh.pallipadi@intel.com   x86: PAT: move tr...
404
405
406
407
408
  				unsigned long pfn, unsigned long size);
  extern int track_pfn_vma_copy(struct vm_area_struct *vma);
  extern void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
  				unsigned long size);
  #endif
5f6e8da70   Andrea Arcangeli   thp: special pmd_...
409
410
411
412
413
414
415
416
417
  #ifndef CONFIG_TRANSPARENT_HUGEPAGE
  static inline int pmd_trans_huge(pmd_t pmd)
  {
  	return 0;
  }
  static inline int pmd_trans_splitting(pmd_t pmd)
  {
  	return 0;
  }
e2cda3226   Andrea Arcangeli   thp: add pmd mang...
418
419
420
421
422
423
424
  #ifndef __HAVE_ARCH_PMD_WRITE
  static inline int pmd_write(pmd_t pmd)
  {
  	BUG();
  	return 0;
  }
  #endif /* __HAVE_ARCH_PMD_WRITE */
5f6e8da70   Andrea Arcangeli   thp: special pmd_...
425
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
428
  #endif /* !__ASSEMBLY__ */
  
  #endif /* _ASM_GENERIC_PGTABLE_H */