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 1cd2d6416bda..201ccaa11f61 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) |
