aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/include/asm/pgtable_64.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/include/asm/pgtable_64.h')
-rw-r--r--arch/sparc/include/asm/pgtable_64.h89
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
76extern unsigned long sparc64_valid_addr_bitmap[];
77
78/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
79static 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
86static 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
722static 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
736static inline pmd_t pmd_mksplitting(pmd_t pmd) 744static 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
761extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, 783extern 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 *);
893extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, 912extern 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
916extern 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
897extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, 920extern 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);
919extern pte_t pgoff_to_pte(unsigned long); 942extern 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
922extern unsigned long sparc64_valid_addr_bitmap[];
923
924/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
925static 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
934extern int page_in_phys_avail(unsigned long paddr); 945extern int page_in_phys_avail(unsigned long paddr);
935 946
936/* 947/*