diff options
Diffstat (limited to 'arch/arm/include/asm/pgtable.h')
-rw-r--r-- | arch/arm/include/asm/pgtable.h | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 1cd2d6416bd..201ccaa11f6 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -162,10 +162,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val); | |||
162 | * entries are stored 1024 bytes below. | 162 | * entries are stored 1024 bytes below. |
163 | */ | 163 | */ |
164 | #define L_PTE_PRESENT (1 << 0) | 164 | #define L_PTE_PRESENT (1 << 0) |
165 | #define L_PTE_FILE (1 << 1) /* only when !PRESENT */ | ||
166 | #define L_PTE_YOUNG (1 << 1) | 165 | #define L_PTE_YOUNG (1 << 1) |
167 | #define L_PTE_BUFFERABLE (1 << 2) /* obsolete, matches PTE */ | 166 | #define L_PTE_FILE (1 << 2) /* only when !PRESENT */ |
168 | #define L_PTE_CACHEABLE (1 << 3) /* obsolete, matches PTE */ | ||
169 | #define L_PTE_DIRTY (1 << 6) | 167 | #define L_PTE_DIRTY (1 << 6) |
170 | #define L_PTE_WRITE (1 << 7) | 168 | #define L_PTE_WRITE (1 << 7) |
171 | #define L_PTE_USER (1 << 8) | 169 | #define L_PTE_USER (1 << 8) |
@@ -264,10 +262,19 @@ extern struct page *empty_zero_page; | |||
264 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) | 262 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) |
265 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) | 263 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) |
266 | #define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) | 264 | #define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) |
267 | #define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) | 265 | |
268 | #define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) | 266 | #define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr)) |
269 | #define pte_unmap(pte) do { } while (0) | 267 | #define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr)) |
270 | #define pte_unmap_nested(pte) do { } while (0) | 268 | #define pte_unmap(pte) __pte_unmap(pte, KM_PTE0) |
269 | #define pte_unmap_nested(pte) __pte_unmap(pte, KM_PTE1) | ||
270 | |||
271 | #ifndef CONFIG_HIGHPTE | ||
272 | #define __pte_map(dir,km) pmd_page_vaddr(*(dir)) | ||
273 | #define __pte_unmap(pte,km) do { } while (0) | ||
274 | #else | ||
275 | #define __pte_map(dir,km) ((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE) | ||
276 | #define __pte_unmap(pte,km) kunmap_atomic((pte - PTRS_PER_PTE), km) | ||
277 | #endif | ||
271 | 278 | ||
272 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) | 279 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) |
273 | 280 | ||
@@ -285,15 +292,6 @@ extern struct page *empty_zero_page; | |||
285 | #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) | 292 | #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) |
286 | #define pte_special(pte) (0) | 293 | #define pte_special(pte) (0) |
287 | 294 | ||
288 | /* | ||
289 | * The following only works if pte_present() is not true. | ||
290 | */ | ||
291 | #define pte_file(pte) (pte_val(pte) & L_PTE_FILE) | ||
292 | #define pte_to_pgoff(x) (pte_val(x) >> 2) | ||
293 | #define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE) | ||
294 | |||
295 | #define PTE_FILE_MAX_BITS 30 | ||
296 | |||
297 | #define PTE_BIT_FUNC(fn,op) \ | 295 | #define PTE_BIT_FUNC(fn,op) \ |
298 | static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } | 296 | static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } |
299 | 297 | ||
@@ -384,16 +382,50 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
384 | 382 | ||
385 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; | 383 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
386 | 384 | ||
387 | /* Encode and decode a swap entry. | 385 | /* |
386 | * Encode and decode a swap entry. Swap entries are stored in the Linux | ||
387 | * page tables as follows: | ||
388 | * | ||
389 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 | ||
390 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ||
391 | * <--------------- offset --------------------> <- type --> 0 0 0 | ||
388 | * | 392 | * |
389 | * We support up to 32GB of swap on 4k machines | 393 | * This gives us up to 63 swap files and 32GB per swap file. Note that |
394 | * the offset field is always non-zero. | ||
390 | */ | 395 | */ |
391 | #define __swp_type(x) (((x).val >> 2) & 0x7f) | 396 | #define __SWP_TYPE_SHIFT 3 |
392 | #define __swp_offset(x) ((x).val >> 9) | 397 | #define __SWP_TYPE_BITS 6 |
393 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) }) | 398 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) |
399 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) | ||
400 | |||
401 | #define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) | ||
402 | #define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT) | ||
403 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) }) | ||
404 | |||
394 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | 405 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) |
395 | #define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) | 406 | #define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) |
396 | 407 | ||
408 | /* | ||
409 | * It is an error for the kernel to have more swap files than we can | ||
410 | * encode in the PTEs. This ensures that we know when MAX_SWAPFILES | ||
411 | * is increased beyond what we presently support. | ||
412 | */ | ||
413 | #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS) | ||
414 | |||
415 | /* | ||
416 | * Encode and decode a file entry. File entries are stored in the Linux | ||
417 | * page tables as follows: | ||
418 | * | ||
419 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 | ||
420 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ||
421 | * <----------------------- offset ------------------------> 1 0 0 | ||
422 | */ | ||
423 | #define pte_file(pte) (pte_val(pte) & L_PTE_FILE) | ||
424 | #define pte_to_pgoff(x) (pte_val(x) >> 3) | ||
425 | #define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE) | ||
426 | |||
427 | #define PTE_FILE_MAX_BITS 29 | ||
428 | |||
397 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | 429 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ |
398 | /* FIXME: this is not correct */ | 430 | /* FIXME: this is not correct */ |
399 | #define kern_addr_valid(addr) (1) | 431 | #define kern_addr_valid(addr) (1) |