diff options
Diffstat (limited to 'arch/sparc/include/asm/pgtable_64.h')
-rw-r--r-- | arch/sparc/include/asm/pgtable_64.h | 89 |
1 files changed, 50 insertions, 39 deletions
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 0f9e94537eee..1a49ffdf9da9 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
@@ -24,7 +24,8 @@ | |||
24 | 24 | ||
25 | /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB). | 25 | /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB). |
26 | * The page copy blockops can use 0x6000000 to 0x8000000. | 26 | * The page copy blockops can use 0x6000000 to 0x8000000. |
27 | * The TSB is mapped in the 0x8000000 to 0xa000000 range. | 27 | * The 8K TSB is mapped in the 0x8000000 to 0x8400000 range. |
28 | * The 4M TSB is mapped in the 0x8400000 to 0x8800000 range. | ||
28 | * The PROM resides in an area spanning 0xf0000000 to 0x100000000. | 29 | * The PROM resides in an area spanning 0xf0000000 to 0x100000000. |
29 | * The vmalloc area spans 0x100000000 to 0x200000000. | 30 | * The vmalloc area spans 0x100000000 to 0x200000000. |
30 | * Since modules need to be in the lowest 32-bits of the address space, | 31 | * Since modules need to be in the lowest 32-bits of the address space, |
@@ -33,7 +34,8 @@ | |||
33 | * 0x400000000. | 34 | * 0x400000000. |
34 | */ | 35 | */ |
35 | #define TLBTEMP_BASE _AC(0x0000000006000000,UL) | 36 | #define TLBTEMP_BASE _AC(0x0000000006000000,UL) |
36 | #define TSBMAP_BASE _AC(0x0000000008000000,UL) | 37 | #define TSBMAP_8K_BASE _AC(0x0000000008000000,UL) |
38 | #define TSBMAP_4M_BASE _AC(0x0000000008400000,UL) | ||
37 | #define MODULES_VADDR _AC(0x0000000010000000,UL) | 39 | #define MODULES_VADDR _AC(0x0000000010000000,UL) |
38 | #define MODULES_LEN _AC(0x00000000e0000000,UL) | 40 | #define MODULES_LEN _AC(0x00000000e0000000,UL) |
39 | #define MODULES_END _AC(0x00000000f0000000,UL) | 41 | #define MODULES_END _AC(0x00000000f0000000,UL) |
@@ -71,6 +73,23 @@ | |||
71 | 73 | ||
72 | #include <linux/sched.h> | 74 | #include <linux/sched.h> |
73 | 75 | ||
76 | extern unsigned long sparc64_valid_addr_bitmap[]; | ||
77 | |||
78 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | ||
79 | static inline bool __kern_addr_valid(unsigned long paddr) | ||
80 | { | ||
81 | if ((paddr >> MAX_PHYS_ADDRESS_BITS) != 0UL) | ||
82 | return false; | ||
83 | return test_bit(paddr >> ILOG2_4MB, sparc64_valid_addr_bitmap); | ||
84 | } | ||
85 | |||
86 | static inline bool kern_addr_valid(unsigned long addr) | ||
87 | { | ||
88 | unsigned long paddr = __pa(addr); | ||
89 | |||
90 | return __kern_addr_valid(paddr); | ||
91 | } | ||
92 | |||
74 | /* Entries per page directory level. */ | 93 | /* Entries per page directory level. */ |
75 | #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) | 94 | #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) |
76 | #define PTRS_PER_PMD (1UL << PMD_BITS) | 95 | #define PTRS_PER_PMD (1UL << PMD_BITS) |
@@ -79,9 +98,12 @@ | |||
79 | /* Kernel has a separate 44bit address space. */ | 98 | /* Kernel has a separate 44bit address space. */ |
80 | #define FIRST_USER_ADDRESS 0 | 99 | #define FIRST_USER_ADDRESS 0 |
81 | 100 | ||
82 | #define pte_ERROR(e) __builtin_trap() | 101 | #define pmd_ERROR(e) \ |
83 | #define pmd_ERROR(e) __builtin_trap() | 102 | pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \ |
84 | #define pgd_ERROR(e) __builtin_trap() | 103 | __FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0)) |
104 | #define pgd_ERROR(e) \ | ||
105 | pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \ | ||
106 | __FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0)) | ||
85 | 107 | ||
86 | #endif /* !(__ASSEMBLY__) */ | 108 | #endif /* !(__ASSEMBLY__) */ |
87 | 109 | ||
@@ -258,8 +280,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) | |||
258 | { | 280 | { |
259 | unsigned long mask, tmp; | 281 | unsigned long mask, tmp; |
260 | 282 | ||
261 | /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347) | 283 | /* SUN4U: 0x630107ffffffec38 (negated == 0x9cfef800000013c7) |
262 | * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8) | 284 | * SUN4V: 0x33ffffffffffee07 (negated == 0xcc000000000011f8) |
263 | * | 285 | * |
264 | * Even if we use negation tricks the result is still a 6 | 286 | * Even if we use negation tricks the result is still a 6 |
265 | * instruction sequence, so don't try to play fancy and just | 287 | * instruction sequence, so don't try to play fancy and just |
@@ -289,10 +311,10 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) | |||
289 | " .previous\n" | 311 | " .previous\n" |
290 | : "=r" (mask), "=r" (tmp) | 312 | : "=r" (mask), "=r" (tmp) |
291 | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | | 313 | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | |
292 | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U | | 314 | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | |
293 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), | 315 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), |
294 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | | 316 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | |
295 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V | | 317 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | |
296 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); | 318 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); |
297 | 319 | ||
298 | return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); | 320 | return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); |
@@ -633,7 +655,7 @@ static inline unsigned long pmd_large(pmd_t pmd) | |||
633 | { | 655 | { |
634 | pte_t pte = __pte(pmd_val(pmd)); | 656 | pte_t pte = __pte(pmd_val(pmd)); |
635 | 657 | ||
636 | return (pte_val(pte) & _PAGE_PMD_HUGE) && pte_present(pte); | 658 | return pte_val(pte) & _PAGE_PMD_HUGE; |
637 | } | 659 | } |
638 | 660 | ||
639 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 661 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
@@ -719,20 +741,6 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd) | |||
719 | return __pmd(pte_val(pte)); | 741 | return __pmd(pte_val(pte)); |
720 | } | 742 | } |
721 | 743 | ||
722 | static inline pmd_t pmd_mknotpresent(pmd_t pmd) | ||
723 | { | ||
724 | unsigned long mask; | ||
725 | |||
726 | if (tlb_type == hypervisor) | ||
727 | mask = _PAGE_PRESENT_4V; | ||
728 | else | ||
729 | mask = _PAGE_PRESENT_4U; | ||
730 | |||
731 | pmd_val(pmd) &= ~mask; | ||
732 | |||
733 | return pmd; | ||
734 | } | ||
735 | |||
736 | static inline pmd_t pmd_mksplitting(pmd_t pmd) | 744 | static inline pmd_t pmd_mksplitting(pmd_t pmd) |
737 | { | 745 | { |
738 | pte_t pte = __pte(pmd_val(pmd)); | 746 | pte_t pte = __pte(pmd_val(pmd)); |
@@ -757,6 +765,20 @@ static inline int pmd_present(pmd_t pmd) | |||
757 | 765 | ||
758 | #define pmd_none(pmd) (!pmd_val(pmd)) | 766 | #define pmd_none(pmd) (!pmd_val(pmd)) |
759 | 767 | ||
768 | /* pmd_bad() is only called on non-trans-huge PMDs. Our encoding is | ||
769 | * very simple, it's just the physical address. PTE tables are of | ||
770 | * size PAGE_SIZE so make sure the sub-PAGE_SIZE bits are clear and | ||
771 | * the top bits outside of the range of any physical address size we | ||
772 | * support are clear as well. We also validate the physical itself. | ||
773 | */ | ||
774 | #define pmd_bad(pmd) ((pmd_val(pmd) & ~PAGE_MASK) || \ | ||
775 | !__kern_addr_valid(pmd_val(pmd))) | ||
776 | |||
777 | #define pud_none(pud) (!pud_val(pud)) | ||
778 | |||
779 | #define pud_bad(pud) ((pud_val(pud) & ~PAGE_MASK) || \ | ||
780 | !__kern_addr_valid(pud_val(pud))) | ||
781 | |||
760 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 782 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
761 | extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, | 783 | extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, |
762 | pmd_t *pmdp, pmd_t pmd); | 784 | pmd_t *pmdp, pmd_t pmd); |
@@ -790,10 +812,7 @@ static inline unsigned long __pmd_page(pmd_t pmd) | |||
790 | #define pud_page_vaddr(pud) \ | 812 | #define pud_page_vaddr(pud) \ |
791 | ((unsigned long) __va(pud_val(pud))) | 813 | ((unsigned long) __va(pud_val(pud))) |
792 | #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) | 814 | #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) |
793 | #define pmd_bad(pmd) (0) | ||
794 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) | 815 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) |
795 | #define pud_none(pud) (!pud_val(pud)) | ||
796 | #define pud_bad(pud) (0) | ||
797 | #define pud_present(pud) (pud_val(pud) != 0U) | 816 | #define pud_present(pud) (pud_val(pud) != 0U) |
798 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) | 817 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) |
799 | 818 | ||
@@ -893,6 +912,10 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); | |||
893 | extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, | 912 | extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, |
894 | pmd_t *pmd); | 913 | pmd_t *pmd); |
895 | 914 | ||
915 | #define __HAVE_ARCH_PMDP_INVALIDATE | ||
916 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | ||
917 | pmd_t *pmdp); | ||
918 | |||
896 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | 919 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
897 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | 920 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, |
898 | pgtable_t pgtable); | 921 | pgtable_t pgtable); |
@@ -919,18 +942,6 @@ extern unsigned long pte_file(pte_t); | |||
919 | extern pte_t pgoff_to_pte(unsigned long); | 942 | extern pte_t pgoff_to_pte(unsigned long); |
920 | #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) | 943 | #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) |
921 | 944 | ||
922 | extern unsigned long sparc64_valid_addr_bitmap[]; | ||
923 | |||
924 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | ||
925 | static inline bool kern_addr_valid(unsigned long addr) | ||
926 | { | ||
927 | unsigned long paddr = __pa(addr); | ||
928 | |||
929 | if ((paddr >> 41UL) != 0UL) | ||
930 | return false; | ||
931 | return test_bit(paddr >> 22, sparc64_valid_addr_bitmap); | ||
932 | } | ||
933 | |||
934 | extern int page_in_phys_avail(unsigned long paddr); | 945 | extern int page_in_phys_avail(unsigned long paddr); |
935 | 946 | ||
936 | /* | 947 | /* |