diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2013-11-27 11:59:27 -0500 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2013-11-29 10:22:59 -0500 |
commit | 3676f9ef5481d614f8c5c857f5319755be248268 (patch) | |
tree | c125b42a392111d30c7c795b055063b23d806663 /arch/arm64/include | |
parent | 4f00130b70e5eee813cc7bc298e0f3fdf79673cc (diff) |
arm64: Move PTE_PROT_NONE higher up
PTE_PROT_NONE means that a pte is present but does not have any
read/write attributes. However, setting the memory type like
pgprot_writecombine() is allowed and such bits overlap with
PTE_PROT_NONE. This causes mmap/munmap issues in drivers that change the
vma->vm_pg_prot on PROT_NONE mappings.
This patch reverts the PTE_FILE/PTE_PROT_NONE shift in commit
59911ca4325d (ARM64: mm: Move PTE_PROT_NONE bit) and moves PTE_PROT_NONE
together with the other software bits.
Signed-off-by: Steve Capper <steve.capper@linaro.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Steve Capper <steve.capper@linaro.org>
Cc: <stable@vger.kernel.org> # 3.11+
Diffstat (limited to 'arch/arm64/include')
-rw-r--r-- | arch/arm64/include/asm/pgtable.h | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 5347b39fdb35..7f2b60affbb4 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
@@ -25,10 +25,11 @@ | |||
25 | * Software defined PTE bits definition. | 25 | * Software defined PTE bits definition. |
26 | */ | 26 | */ |
27 | #define PTE_VALID (_AT(pteval_t, 1) << 0) | 27 | #define PTE_VALID (_AT(pteval_t, 1) << 0) |
28 | #define PTE_PROT_NONE (_AT(pteval_t, 1) << 2) /* only when !PTE_VALID */ | 28 | #define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */ |
29 | #define PTE_FILE (_AT(pteval_t, 1) << 3) /* only when !pte_present() */ | ||
30 | #define PTE_DIRTY (_AT(pteval_t, 1) << 55) | 29 | #define PTE_DIRTY (_AT(pteval_t, 1) << 55) |
31 | #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) | 30 | #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) |
31 | /* bit 57 for PMD_SECT_SPLITTING */ | ||
32 | #define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * VMALLOC and SPARSEMEM_VMEMMAP ranges. | 35 | * VMALLOC and SPARSEMEM_VMEMMAP ranges. |
@@ -357,18 +358,20 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; | |||
357 | 358 | ||
358 | /* | 359 | /* |
359 | * Encode and decode a swap entry: | 360 | * Encode and decode a swap entry: |
360 | * bits 0, 2: present (must both be zero) | 361 | * bits 0-1: present (must be zero) |
361 | * bit 3: PTE_FILE | 362 | * bit 2: PTE_FILE |
362 | * bits 4-8: swap type | 363 | * bits 3-8: swap type |
363 | * bits 9-63: swap offset | 364 | * bits 9-57: swap offset |
364 | */ | 365 | */ |
365 | #define __SWP_TYPE_SHIFT 4 | 366 | #define __SWP_TYPE_SHIFT 3 |
366 | #define __SWP_TYPE_BITS 6 | 367 | #define __SWP_TYPE_BITS 6 |
368 | #define __SWP_OFFSET_BITS 49 | ||
367 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) | 369 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) |
368 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) | 370 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) |
371 | #define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1) | ||
369 | 372 | ||
370 | #define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) | 373 | #define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) |
371 | #define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT) | 374 | #define __swp_offset(x) (((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK) |
372 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) }) | 375 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) }) |
373 | 376 | ||
374 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | 377 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) |
@@ -382,15 +385,15 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; | |||
382 | 385 | ||
383 | /* | 386 | /* |
384 | * Encode and decode a file entry: | 387 | * Encode and decode a file entry: |
385 | * bits 0, 2: present (must both be zero) | 388 | * bits 0-1: present (must be zero) |
386 | * bit 3: PTE_FILE | 389 | * bit 2: PTE_FILE |
387 | * bits 4-63: file offset / PAGE_SIZE | 390 | * bits 3-57: file offset / PAGE_SIZE |
388 | */ | 391 | */ |
389 | #define pte_file(pte) (pte_val(pte) & PTE_FILE) | 392 | #define pte_file(pte) (pte_val(pte) & PTE_FILE) |
390 | #define pte_to_pgoff(x) (pte_val(x) >> 4) | 393 | #define pte_to_pgoff(x) (pte_val(x) >> 3) |
391 | #define pgoff_to_pte(x) __pte(((x) << 4) | PTE_FILE) | 394 | #define pgoff_to_pte(x) __pte(((x) << 3) | PTE_FILE) |
392 | 395 | ||
393 | #define PTE_FILE_MAX_BITS 60 | 396 | #define PTE_FILE_MAX_BITS 55 |
394 | 397 | ||
395 | extern int kern_addr_valid(unsigned long addr); | 398 | extern int kern_addr_valid(unsigned long addr); |
396 | 399 | ||